<?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>scribe &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/tag/scribe/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Wed, 28 Oct 2015 12:42:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>
	<item>
		<title>Enabling user callbacks during zoom/pan</title>
		<link>https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enabling-user-callbacks-during-zoom-pan</link>
					<comments>https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 28 Oct 2015 12:42:03 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[Listeners]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Undocumented function]]></category>
		<category><![CDATA[Listener]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[scribe]]></category>
		<category><![CDATA[uimode]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=6043</guid>

					<description><![CDATA[<p>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan">Enabling user callbacks during zoom/pan</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/user-defined-tab-completions-take-2" rel="bookmark" title="User-defined tab completions &#8211; take 2">User-defined tab completions &#8211; take 2 </a> <small>Matlab has changed the mechanism that enables user-defined tab-completion of function inputs. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/determining-axes-zoom-state" rel="bookmark" title="Determining axes zoom state">Determining axes zoom state </a> <small>The information of whether or not an axes is zoomed or panned can easily be inferred from an internal undocumented object....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a" rel="bookmark" title="Matlab callbacks for Java events in R2014a">Matlab callbacks for Java events in R2014a </a> <small>R2014a changed the way in which Java objects expose events as Matlab callbacks. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>An annoying side-effect of Matlab figure uimodes (zoom, pan and rotate3d) is that they disable the user&#8217;s figure-wide callbacks (<b>KeyPressFcn</b>, <b>KeyReleaseFcn</b>, <b>WindowKeyPressFcn</b>, <b>WindowKeyReleaseFcn</b>, <b>WindowButtonUpFcn</b>, <b>WindowButtonDownFcn</b> and <b>WindowScrollWheelFcn</b>). In most cases, users will indeed expect the mouse and keyboard behavior to change when these modes are active (selecting a zoom region with the mouse for instance). However, in certain cases we may need to retain our custom callback behavior even when the modes are active. This is particularly relevant for the keyboard callbacks, which are not typically used to control the modes and yet may be very important for our figure&#8217;s interactive functionality. Unfortunately, Matlab&#8217;s mode manager installs property listeners that prevent users from modifying these callback when any mode is active:</p>
<div class="wp_syntax">
<div class="code">
<pre class="matlab" style="font-family:monospace;">&gt;&gt; hFig=<span style="color: #0000FF;">figure</span>; <span style="color: #0000FF;">plot</span><span style="color: #080;">(</span><span style="color: #33f;">1</span><span style="color: #F0F;">:</span><span style="color: #33f;">5</span><span style="color: #080;">)</span>; <span style="color: #0000FF;">zoom</span> <span style="color:#A020F0;">on</span>
&gt;&gt; <span style="color: #0000FF;">set</span><span style="color: #080;">(</span>hFig, <span style="color:#A020F0;">'KeyPressFcn'</span>, <span style="color: #F0F;">@</span>myKeyPressCallback<span style="color: #080;">)</span>
<span style="color: orange;">Warning: Setting the "KeyPressFcn" property is not permitted while this mode is active.
(Type "warning off MATLAB:modes:mode:InvalidPropertySet" to suppress this warning.)
&nbsp;
&gt; In matlab.uitools.internal.uimodemanager&gt;localModeWarn (line 211)
  In matlab.uitools.internaluimodemanager&gt;@(obj,evd)(localModeWarn(obj,evd,hThis)) (line 86)</span>
&nbsp;
&gt;&gt; <span style="color: #0000FF;">get</span><span style="color: #080;">(</span>hFig, <span style="color:#A020F0;">'KeyPressFcn'</span><span style="color: #080;">)</span>  <span style="color: #228B22;">% the KeyPressFcn callback set by the mode manager</span>
ans =
    <span style="color: #F0F;">@</span>localModeKeyPressFcn
    <span style="color: #080;">[</span>1x1 matlab.<span style="">uitools</span>.<span style="">internal</span>.<span style="">uimode</span><span style="color: #080;">]</span>
    <span style="color: #080;">{</span>1x2 cell                          <span style="color: #080;">}</span></pre>
</div>
</div>
<p>The question of how to override this limitation has appeared multiple times over the years in the CSSM newsgroup (<a target="_blank" rel="nofollow" href="https://www.mathworks.com/matlabcentral/newsreader/view_thread/235114">example1</a>, <a target="_blank" rel="nofollow" href="https://www.mathworks.com/matlabcentral/newsreader/view_thread/283529">example2</a>) and the Answers forum, <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/answers/251339-re-enable-keypress-capture-in-pan-or-zoom-mode">most recently yesterday</a>, so I decided to dedicate today&#8217;s article to this issue.<br />
<span id="more-6043"></span><br />
In Matlab GUI, a &#8220;mode&#8221; (aka <i>uimode</i>) is a set of defined behaviors that may be set for any figure window and activated/deactivated via the figure&#8217;s menu, toolbar or programmatically. Examples of predefined modes are plot edit, zoom, pan, rotate3d and data-cursor. Only one mode can be active in a figure at any one time – this is managed via a figure&#8217;s <code>ModeManager</code>. Activating a figure mode automatically deactivates any other active mode, as can be seen when switching between plot edit, zoom, pan, rotate3d and data-cursor modes.<br />
This mode manager is implemented in the <i><b>uimodemanager</b></i> class in <i>%matlabroot%/toolbox/matlab/uitools/+matlab/+uitools/internal/@uimodemanager/uimodemanager.m</i> and its sibling functions in the same folder. Until recently it used to be implemented in Matlab&#8217;s old class system, but was recently converted to the new MCOS (<i><b>classdef</b></i>) format, without an apparent major overhaul of the underlying logic (which I think is a pity, but refactoring naturally has lower priority than fixing bugs or adding new functionality).<br />
Anyway, until HG2 (R2014b), the solution for bypassing the mode-manager&#8217;s callbacks hijacking was as follows (credit: Walter Roberson):</p>
<pre lang='matlab'>
% This will only work in HG1 (R2014a or earlier)
hManager = uigetmodemanager(hFig);
set(hManager.WindowListenerHandles, 'Enable', 'off');
set(hFig, 'WindowKeyPressFcn', []);
set(hFig, 'KeyPressFcn', @myKeyPressCallback);
</pre>
<p>In HG2 (R2014b), the interface of <b>WindowListenerHandles</b> changed and the above code no longer works:</p>
<div class="wp_syntax">
<div class="code">
<pre class="matlab" style="font-family:monospace;">&gt;&gt; <span style="color: #0000FF;">set</span><span style="color: #080;">(</span>hManager.<span style="">WindowListenerHandles</span>, <span style="color:#A020F0;">'Enable'</span>, <span style="color:#A020F0;">'off'</span><span style="color: #080;">)</span>;
<span style="color: #FF0000;">Error using set
Cannot find 'set' method for event.proplistener class</span>.</pre>
</div>
</div>
<p>Luckily, in MathWorks&#8217; refactoring to MCOS, the property name <b>WindowListenerHandles</b> was not changed, nor its status as a public read-only hidden property. So we can still access it directly. The only thing that changed is its meta-properties, and this is due not to any change in the mode-manager&#8217;s code, but rather to a much more general change in the implementation of the <i><b>event.proplistener</b></i> class:</p>
<div class="wp_syntax">
<div class="code">
<pre class="matlab" style="font-family:monospace;">&gt;&gt; hManager.<span style="">WindowListenerHandles</span><span style="color: #080;">(</span><span style="color: #33f;">1</span><span style="color: #080;">)</span>
ans =
  <span style="color: #0000FF;text-decoration: underline;">proplistener</span> with properties:
&nbsp;
       Object<span style="color: #F0F;">:</span> <span style="color: #080;">{</span><span style="color: #080;">[</span>1x1 Figure<span style="color: #080;">]</span><span style="color: #080;">}</span>
       Source<span style="color: #F0F;">:</span> <span style="color: #080;">{</span>7x1 cell<span style="color: #080;">}</span>
    EventName<span style="color: #F0F;">:</span> <span style="color:#A020F0;">'PreSet'</span>
     Callback<span style="color: #F0F;">:</span> <span style="color: #F0F;">@</span><span style="color: #080;">(</span>obj,evd<span style="color: #080;">)</span><span style="color: #080;">(</span>localModeWarn<span style="color: #080;">(</span>obj,evd,hThis<span style="color: #080;">)</span><span style="color: #080;">)</span>
      Enabled<span style="color: #F0F;">:</span> <span style="color: #33f;">0</span>
    Recursive<span style="color: #F0F;">:</span> <span style="color: #33f;">0</span></pre>
</div>
</div>
<p>In the new <i><b>proplistener</b></i>, the <b>Enabled</b> meta-property is now a boolean (logical) value rather than a string, and was renamed <b>Enabled</b> in place of the original <b>Enable</b>. Also, the new <i><b>proplistener</b></i> doesn&#8217;t inherit <i><b>hgsetget</b></i>, so it does not have <i><b>set</b></i> and <i><b>get</b></i> methods, which is why we got an error above; instead, we should use direct dot-notation.<br />
In summary, the code that should now be used, and is backward compatible with old HG1 releases as well as new HG2 releases, is as follows:</p>
<pre lang='matlab'>
% This should work in both HG1 and HG2:
hManager = uigetmodemanager(hFig);
try
    set(hManager.WindowListenerHandles, 'Enable', 'off');  % HG1
catch
    [hManager.WindowListenerHandles.Enabled] = deal(false);  % HG2
end
set(hFig, 'WindowKeyPressFcn', []);
set(hFig, 'KeyPressFcn', @myKeyPressCallback);
</pre>
<p>During an active mode, the mode-manager disables user-configured mouse and keyboard callbacks, in order to prevent interference with the mode&#8217;s functionality. For example, mouse clicking during zoom mode has a very specific meaning, and user-configured callbacks might interfere with it. Understanding this and taking the proper precautions (for example: chaining the default mode&#8217;s callback at the beginning or end of our own callback), we can override this default behavior, as shown above.<br />
Note that the entire mechanism of mode-manager (and the related <a target="_blank" href="/articles/tag/scribe">scribe objects</a>) is undocumented and might change without notice in future Matlab releases. We were fortunate in the current case that the change was small enough that a simple workaround could be found, but this may possibly not be the case next time around. It&#8217;s impossible to guess when such features will eventually break: it might happen in the very next release, or 20 years in the future. Since there are no real alternatives, we have little choice other than to use these features, and document the risk (the fact that they use undocumented aspects). In your documentation/comments, add a link back here so that if something ever breaks you&#8217;d be able to check if I posted any fix or workaround.<br />
For the sake of completeness, here is a listing of the accessible properties (regular and hidden) of both the mode-manager as well as the zoom uimode, in R2015b:</p>
<pre lang='matlab'>
>> warning('off', 'MATLAB:structOnObject');  % suppress warning about using structs (yes we know it's not good for us...)
>> struct(hManager)
ans =
                    CurrentMode: [1x1 matlab.uitools.internal.uimode]
                  DefaultUIMode: ''
                       Blocking: 0
                   FigureHandle: [1x1 Figure]
          WindowListenerHandles: [1x2 event.proplistener]
    WindowMotionListenerHandles: [1x2 event.proplistener]
                 DeleteListener: [1x1 event.listener]
            PreviousWindowState: []
                RegisteredModes: [1x1 matlab.uitools.internal.uimode]
>> struct(hManager.CurrentMode)
ans =
    WindowButtonMotionFcnInterrupt: 0
                UIControlInterrupt: 0
                   ShowContextMenu: 1
                         IsOneShot: 0
                    UseContextMenu: 'on'
                          Blocking: 0
               WindowJavaListeners: []
                    DeleteListener: [1x1 event.listener]
              FigureDeleteListener: [1x1 event.listener]
                    BusyActivating: 0
                              Name: 'Exploration.Zoom'
                      FigureHandle: [1x1 Figure]
             WindowListenerHandles: [1x2 event.proplistener]
                   RegisteredModes: []
                       CurrentMode: []
               ModeListenerHandles: []
               WindowButtonDownFcn: {@localWindowButtonDownFcn  [1x1 matlab.uitools.internal.uimode]}
                 WindowButtonUpFcn: []
             WindowButtonMotionFcn: {@localMotionFcn  [1x1 matlab.uitools.internal.uimode]}
                 WindowKeyPressFcn: []
               WindowKeyReleaseFcn: []
              WindowScrollWheelFcn: {@localButtonWheelFcn  [1x1 matlab.uitools.internal.uimode]}
                     KeyReleaseFcn: []
                       KeyPressFcn: {@localKeyPressFcn  [1x1 matlab.uitools.internal.uimode]}
                      ModeStartFcn: {@localStartZoom  [1x1 matlab.uitools.internal.uimode]}
                       ModeStopFcn: {@localStopZoom  [1x1 matlab.uitools.internal.uimode]}
                  ButtonDownFilter: []
                     UIContextMenu: []
                     ModeStateData: [1x1 struct]
                WindowFocusLostFcn: []
          UIControlSuspendListener: [1x1 event.listener]
      UIControlSuspendJavaListener: [1x1 handle.listener]
                   UserButtonUpFcn: []
               PreviousWindowState: []
                 ActionPreCallback: []
                ActionPostCallback: []
           WindowMotionFcnListener: [1x1 event.listener]
                       FigureState: [1x1 struct]
                        ParentMode: []
                     DefaultUIMode: ''
             CanvasContainerHandle: []
                            Enable: 'on'
</pre>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan">Enabling user callbacks during zoom/pan</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/user-defined-tab-completions-take-2" rel="bookmark" title="User-defined tab completions &#8211; take 2">User-defined tab completions &#8211; take 2 </a> <small>Matlab has changed the mechanism that enables user-defined tab-completion of function inputs. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/determining-axes-zoom-state" rel="bookmark" title="Determining axes zoom state">Determining axes zoom state </a> <small>The information of whether or not an axes is zoomed or panned can easily be inferred from an internal undocumented object....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a" rel="bookmark" title="Matlab callbacks for Java events in R2014a">Matlab callbacks for Java events in R2014a </a> <small>R2014a changed the way in which Java objects expose events as Matlab callbacks. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan/feed</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Pinning annotations to graphs</title>
		<link>https://undocumentedmatlab.com/articles/pinning-annotations-to-graphs?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pinning-annotations-to-graphs</link>
					<comments>https://undocumentedmatlab.com/articles/pinning-annotations-to-graphs#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 12 Dec 2012 18:00:51 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Undocumented function]]></category>
		<category><![CDATA[getundoc]]></category>
		<category><![CDATA[Optical illusion]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[scribe]]></category>
		<category><![CDATA[UDD]]></category>
		<category><![CDATA[UIInspect]]></category>
		<category><![CDATA[Undocumented property]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=3398</guid>

					<description><![CDATA[<p>Annotation object can be programmatically set at, and pinned-to, plot axes data points. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/pinning-annotations-to-graphs">Pinning annotations to graphs</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/plotly-graphs" rel="bookmark" title="Plotly graphs">Plotly graphs </a> <small>Plotly charts can be created and customized in Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/jfreechart-graphs-and-gauges" rel="bookmark" title="JFreeChart graphs and gauges">JFreeChart graphs and gauges </a> <small>JFreeChart is an open-source charting library that can easily be integrated in Matlab...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plotly-graphs-in-ipython-notebook" rel="bookmark" title="Plotly graphs in IPython Notebook">Plotly graphs in IPython Notebook </a> <small>Plotly graphs can be embedded in an IPython Notebook directly from Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/bug-and-workaround-in-timeseries-plot" rel="bookmark" title="Bug and workaround in timeseries plot">Bug and workaround in timeseries plot </a> <small>Matlab's internal hgconvertunits function has a bug that affects timeseries plots. Luckily there is a simple workaround....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Many Matlab users are aware of Matlab&#8217;s <a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/matlab/creating_plots/how-to-annotate-graphs.html">annotation functionality</a>, which enables us to assign graphic elements such as arrows, lines, ellipses and text labels to Matlab figures. Matlab has a corresponding built-in function, <i><b>annotation</b></i>, that enables creation of annotation objects. Through the handle returned by <i><b>annotation</b></i> we can customize the annotation&#8217;s appearance (for example, line width/style or text font properties).</p>
<h3 id="limitations">Limitations of Matlab annotations</h3>
<p>Unfortunately, <i><b>annotation</b></i> has several major deficiencies, that are in fact related:<br />
<figure style="width: 406px" class="wp-caption alignright"><img fetchpriority="high" decoding="async" alt="A Matlab text-arrow annotation (unpinned)" src="https://undocumentedmatlab.com/images/Annotation_unpinned_animated.gif" title="A Matlab text-arrow annotation (unpinned)" width="406" height="298" /><figcaption class="wp-caption-text">A Matlab text-arrow annotation (unpinned)</figcaption></figure></p>
<ol>
<li><i><b>annotation</b></i> requires us to specify the annotation&#8217;s position in normalized <u>figure</u> units. Often, we are interested in an annotation on a plot axes that does NOT span the entire figure&#8217;s content area. To correctly convert the position from plot axes data coordinates to figure coordinates requires non-trivial calculations.</li>
<li>The created annotation is NOT pinned to the plot axes by default. This means that the annotation retains its relative position in the figure when the plot is zoomed, panned or rotated. This results in unintelligible and misleading annotations. We can indeed pin the annotation to the graph, but this requires delicate manual interaction (click the Edit Plot toolbar icon, then right-click the relevant annotation end-point, then select &#8220;Pin to Axes&#8221; from context menu). Unfortunately, the annotation handle does not provide a documented way to do this programmatically.</li>
<li>Finally, the annotation objects are only displayed on top of plot axes &#8211; they are obscured by any GUI uicontrols that may happen to be present in the figure.</li>
</ol>
<p>All of these limitations originate from the underlying implementation of annotation objects in Matlab. This is based on a transparent hidden axes that spans the entire figure&#8217;s content area, on which the annotations are being drawn (also called the <i>scribe layer</i>). The annotations may appear to be connected to the plot axes, but this is merely a visual illusion. In fact, they are located in a separate axes layer. For this reason, <i><b>annotation</b></i> requires figure position &#8211; in fact, the annotation has no information about the axes beneath it. Since plot axes are always obscured by uicontrols, so too is the annotation layer.<br />
Matlab&#8217;s implementation of annotation is an attempt to replicate Java&#8217;s standard <a target="_blank" rel="nofollow" href="http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html">glass-pane mechanism</a>. But whereas the Java glass-pane is a true transparent layer, on top of all other window components (<a target="_blank" rel="nofollow" href="http://www.codebeach.com/2008/03/introduction-to-glass-panes-in-swing.html">examples</a>), Matlab&#8217;s implementation only works for axes.<br />
Oh well, it&#8217;s better than nothing, I guess. But still, it would be nice if we could specify the annotation in graph (plot axes) data units, and have it pinned automatically without requiring manual user interaction.<br />
<span id="more-3398"></span></p>
<h3 id="Debugging">Debugging the problem</h3>
<p>The obvious first place to start debugging this issue is to go to the annotation handle&#8217;s context-menu (accessible via the <b>UIContextMenu</b> property), drill down to the &#8220;Pin&#8221; menu item and take a look at its callback. We could then use the <i><b><a target="_blank" href="/articles/hgfeval/">hgfeval</a></b></i> function to execute this callback programmatically. Unfortunately, this does not work well, because the context-menu is empty when the annotation is first created. A context-menu is only assigned to the annotation after the Edit Plot toolbar button and then the annotation object are clicked.<br />
Being too lazy in nature to debug this all the way through, I opted for an easier route: I started the Profiler just prior to clicking the context-menu&#8217;s &#8220;Pin to Axes&#8221;, and stopped it immediately afterwards. This showed me the code path (beneath <i>%matlabroot%/toolbox/matlab/scribe/</i>), and placing breakpoints in key code lines enabled me to debug the process step-by-step. This in turn enabled me to take the essence of the pinning code and implement it in my stand-alone application code.<br />
Believe me when I say that the scribe code is complex (anyone say convoluted?). So I&#8217;ll spare you the gruesome details and skip right to the chase.</p>
<h3 id="solution">The solution</h3>
<h5 id="positioning">Positioning the annotation in axes data units</h5>
<p>The first step is to ensure that the initial annotation position is within the figure bounds. Otherwise, the <i><b>annotation</b></i> function will shout. Note that it is ok to move the annotation outside the figure bounds later on (via panning/zooming) &#8211; it is only the initial annotation creation that must be within the figure bounds (i.e., between 0.0-1.0 in normalized X and Y units):</p>
<pre lang='matlab'>
% Prepare the annotation's X position
% Note: we need 2 X values: one for the annotation's head, another for the tail
x = [xValue, xValue];
xlim = get(hAxes,'XLim');
% Prepare the annotation's Y position
% Note: we need 2 Y values: one for the annotation's head, another for the tail
% Note: we use a static Y position here, spanning the center of the axes.
% ^^^^  We could have used some other Y data value for this
yLim = get(hAxes,'YLim');
y = yLim(1) + 0*sum(yLim) + [0.1,0]*diff(ylim);  % TODO: handle reverse, log Y axes
% Ensure that the annotation fits in the window by enlarging
% the axes limits as required
if xValue < xlim(1) || xValue > xlim(2)
    hold(hAxes,'on');
    plot(hAxes,xValue,y(2),'-w');
    drawnow;
    % YLim may have changed, so recalculate y
    yLim = get(hAxes,'YLim');
    y = yLim(1) + 0*sum(yLim) + [0.1,0]*diff(ylim);  % TODO: handle reverse, log Y-axes
end
</pre>
<p>Next, we convert our plot data units, in order to get the annotation&#8217;s requested position in the expected figure units. For this we use <i>%matlabroot%/toolbox/matlab/scribe/@scribe/@scribepin/topixels.m</i>. This is an internal method of the <code>scribepin</code> UDD class, so in order to use it we need to create a dummy <code>scribepin</code> object. <i>topixels</i> then converts the dummy object&#8217;s position from axes data units to pixel units. We then use the undocumented <i><b><a target="_blank" href="/articles/bug-and-workaround-in-timeseries-plot/">hgconvertunits</a></b></i> function to convert from pixel units into normalized figure units:</p>
<pre lang='matlab'>
% Convert axes data position to figure normalized position
% uses %matlabroot%/toolbox/matlab/scribe/@scribe/@scribepin/topixels.m
scribepin = scribe.scribepin('parent',hAxes,'DataAxes',hAxes,'DataPosition',[x;y;[0,0]]');
figPixelPos = scribepin.topixels;
hFig = ancestor(hAxes,'figure');
figPos = getpixelposition(hFig);
figPixelPos(:,2) = figPos(4) - figPixelPos([2,1],2);
figNormPos = hgconvertunits(hFig,[figPixelPos(1,1:2),diff(figPixelPos)],'pixels','norm',hFig);
annotationX = figNormPos([1,1]);
annotationY = figNormPos([2,2]) + figNormPos(4)*[1,0];
</pre>
<h5 id="pinning">Pinning the annotation to the axes data</h5>
<p>Finally, we use the annotation handle&#8217;s <i>pinAtAffordance()</i> method and set the <b>Pin.DataPosition</b> property to the requested X,Y values (we need to do both of these, otherwise the annotation will jump around when we zoom/pan):<br />
<center><figure style="width: 406px" class="wp-caption alignright"><img decoding="async" alt="A Matlab text-arrow annotation (pinned)" src="https://undocumentedmatlab.com/images/Annotation_pinned_animated.gif" title="A Matlab text-arrow annotation (pinned)" width="406" height="298" /><figcaption class="wp-caption-text">A Matlab text-arrow annotation (pinned)</figcaption></figure></center></p>
<pre lang='matlab'>
% Ensure that the annotation is within the axes bounds, then display it
if any([annotationX,annotationY] < 0) || any([annotationX,annotationY] > 1)
    % Annotation position is outside axes boundaries, so bail out without drawing
    hAnnotation = handle([]);
elseif ~isempty(annotationObj)
    % Create a text-arrow annotation with the requested string at the requested position
    hAnnotation = handle(annotation('textarrow', annotationX, annotationY, ...
                                    'String',annotationStr, 'TextColor','b', 'Tag','annotation'));
    % Example for setting annotation properties
    hAnnotation.TextEdgeColor = [.8,.8,.8];
    % Pin the annotation object to the required axes position
    % Note: some of the following could fail in certain cases - never mind
    try
        hAnnotation.pinAtAffordance(1);
        hAnnotation.pinAtAffordance(2);
        hAnnotation.Pin(1).DataPosition = [xValue, y(1), 0];
        hAnnotation.Pin(2).DataPosition = [xValue, y(2), 0];
    catch
        % never mind - ignore (no error)
    end
end
</pre>
<p>p.s. Notice that all this relies on pure Matlab code (i.e., no mention of the dreaded J-word&#8230;). In fact, practically the entire scribe code is available in m-file format in the base Matlab installation. Masochistic readers may find many hours of pleasure sifting through the scribe code functionality for interesting nuggets such as the one above. If you ever find any interesting items, please drop me an email, or post a comment below.</p>
<h3 id="undocumented">Undocumented annotation properties</h3>
<p>Annotation objects have a <u>huge</u> number of undocumented properties. In fact, they have more undocumented properties than documented ones. You can see this using my <i><b><a target="_blank" href="/articles/uiinspect/">uiinspect</a></b></i> or <i><b><a target="_blank" href="/articles/getundoc-get-undocumented-object-properties/">getundoc</a></b></i> utilities. Here is the list for a simple text-arrow annotation, such as the one that we used above:</p>
<pre lang='matlab'>
>> getundoc(hAnnotation)
ans =
              ALimInclude: 'on'
                   Afsize: 6
          ApplicationData: [1x1 struct]
                 Behavior: [1x1 struct]
              CLimInclude: 'on'
               ColorProps: {5x1 cell}
     EdgeColorDescription: 'Color'
        EdgeColorProperty: 'Color'
                  Editing: 'off'
                EraseMode: 'normal'
     FaceColorDescription: 'Head Color'
        FaceColorProperty: 'HeadColor'
             FigureResize: 0
            HeadBackDepth: 0.35
                HeadColor: [0 0 0]
            HeadColorMode: 'auto'
            HeadEdgeColor: [0 0 0]
            HeadFaceAlpha: 1
            HeadFaceColor: [0 0 0]
               HeadHandle: [1x1 patch]
         HeadHypocycloidN: 3
            HeadLineStyle: '-'
            HeadLineWidth: 0.5
               HeadRosePQ: 2
                 HeadSize: 10
             HelpTopicKey: ''
          IncludeRenderer: 'on'
                 MoveMode: 'mouseover'
                    NormX: [0.2 0.4]
                    NormY: [0.5 0.7]
                      Pin: [0x1 double]
                   PinAff: [1 2]
           PinContextMenu: [2x1 uimenu]
                PinExists: [0 0]
              PixelBounds: [0 0 0 0]
        PropertyListeners: [8x1 handle.listener]
        ScribeContextMenu: [9x1 uimenu]
                 Selected: 'off'
             Serializable: 'on'
                ShapeType: 'textarrow'
                    Srect: [2x1 line]
           StoredPosition: []
                TailColor: [0 0 0]
               TailHandle: [1x1 line]
            TailLineStyle: '-'
            TailLineWidth: 0.5
     TextColorDescription: 'Text Color'
            TextColorMode: 'auto'
        TextColorProperty: 'TextColor'
        TextEdgeColorMode: 'manual'
            TextEraseMode: 'normal'
               TextHandle: [1x1 text]
         UpdateInProgress: 0
    VerticalAlignmentMode: 'auto'
              XLimInclude: 'on'
              YLimInclude: 'on'
              ZLimInclude: 'on'
</pre>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/pinning-annotations-to-graphs">Pinning annotations to graphs</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/plotly-graphs" rel="bookmark" title="Plotly graphs">Plotly graphs </a> <small>Plotly charts can be created and customized in Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/jfreechart-graphs-and-gauges" rel="bookmark" title="JFreeChart graphs and gauges">JFreeChart graphs and gauges </a> <small>JFreeChart is an open-source charting library that can easily be integrated in Matlab...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plotly-graphs-in-ipython-notebook" rel="bookmark" title="Plotly graphs in IPython Notebook">Plotly graphs in IPython Notebook </a> <small>Plotly graphs can be embedded in an IPython Notebook directly from Matlab. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/bug-and-workaround-in-timeseries-plot" rel="bookmark" title="Bug and workaround in timeseries plot">Bug and workaround in timeseries plot </a> <small>Matlab's internal hgconvertunits function has a bug that affects timeseries plots. Luckily there is a simple workaround....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/pinning-annotations-to-graphs/feed</wfw:commentRss>
			<slash:comments>13</slash:comments>
		
		
			</item>
		<item>
		<title>Multi-column (grid) legend</title>
		<link>https://undocumentedmatlab.com/articles/multi-column-grid-legend?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=multi-column-grid-legend</link>
					<comments>https://undocumentedmatlab.com/articles/multi-column-grid-legend#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Mon, 07 Feb 2011 18:00:04 +0000</pubDate>
				<category><![CDATA[Guest bloggers]]></category>
		<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Hidden property]]></category>
		<category><![CDATA[Listeners]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Adrian Cherry]]></category>
		<category><![CDATA[Listener]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[scribe]]></category>
		<category><![CDATA[Undocumented property]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=2071</guid>

					<description><![CDATA[<p>This article explains how to use undocumented axes listeners for implementing multi-column plot legends</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/multi-column-grid-legend">Multi-column (grid) legend</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/multi-line-uitable-column-headers" rel="bookmark" title="Multi-line uitable column headers">Multi-line uitable column headers </a> <small>Matlab uitables can present long column headers in multiple lines, for improved readability. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/transparent-legend" rel="bookmark" title="Transparent legend">Transparent legend </a> <small>Matlab chart legends are opaque be default but can be made semi- or fully transparent. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-legend-customization" rel="bookmark" title="Plot legend customization">Plot legend customization </a> <small>Matlab plot legends and their internal components can be customized using a variety of undocumented properties that are easily accessible. ...</small></li>
<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>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p><i>I would like to welcome guest blogger Adrian Cherry. Adrian will describe a very handy utility that shows how basic built-in Matlab functions can be improved and customized by just a bit of fiddling under Matlab&#8217;s hood.</i></p>
<h3 id="Legend">Legend Plotting</h3>
<p>Whilst I enjoy using the many time saving features of Matlab, one area where I feel it suffers is the technical plotting and annotation. This tale relates the development of a legend plotting routine, <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/29248-gridlegend-a-multi-column-format-for-legends">gridLegend</a>, in an effort to improve the presentation.<br />
In my day job we have a requirement to condense a large quantity of data onto summary charts. However, there is only so much data consolidation possible before you start losing the information required. We often need to plot 40 or 50 lines of test data to visualize trends or outliers, using the legend to identify the number of test hours against each test specimen.<br />
Using the standard Matlab <i><b>legend</b></i> function resulted in a long legend over twice the size of the associated plot:<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img decoding="async" alt="Standard Matlab legend" src="https://undocumentedmatlab.com/images/Legend1.png" title="Standard Matlab legend" width="450" height="337" /><figcaption class="wp-caption-text">Standard Matlab legend</figcaption></figure></center><br />
I wanted some way of generating a more compact legend format.<br />
Fortunately earlier in the year, an entry on Matlab Central allowing a multi-column legend to be generated was posted, <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/27389-columnlegend">columnlegend</a>. Although lacking some features, columnlegend gave me a good start on developing what I wanted for a multi column legend, culminating in <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/29248-gridlegend-a-multi-column-format-for-legends">gridLegend</a>:<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Multi-column legend" src="https://undocumentedmatlab.com/images/Legend2.png" title="Multi-column legend" width="450" height="398" /><figcaption class="wp-caption-text">Multi-column legend</figcaption></figure></center></p>
<h3 id="Undocumented">Delving into the Undocumented Matlab</h3>
<p>So where is the link with undocumented Matlab?<br />
As mentioned in the original columnlegend entry, it was relatively simple to redraw the legend as required on the screen. However, as soon as the figure was printed or exported to an image file, internal Matlab workings would redraw the figure, including the legend, thereby undoing my careful legend crafting, squeezing it back into one column (Yuck!):<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Matlab-reverted multi-column legend" src="https://undocumentedmatlab.com/images/Legend3.png" title="Matlab-reverted multi-column legend" width="450" height="398" /><figcaption class="wp-caption-text">Matlab-reverted multi-column legend</figcaption></figure></center><br />
As we wanted to automatically output images files, I had to delve into the hidden areas of Matlab to try to solve this problem.<br />
My initial thought was to find out where the figure got redrawn for printing or export and override the standard legend call with a call to my new function. I couldn&#8217;t find the obvious culprit, stepping as far as I could through the print function there didn&#8217;t appear to be any call to the legend function.<br />
In my search for information on how the legend worked I found the undocumented Matlab article about generating <a target="_blank" href="/articles/legend-semi-documented-feature/">dynamic legends</a>. This dynamic-legend post covered details about attaching a listener to a child of the legend axes, in Matlab the legend function creates its own set of axes on the figure to display the legend.<br />
Armed with the information that legend axes objects could have listeners attached, I considered that these might be the source of redrawing the legend for printing. So with the legend I had generated I took a look at what listeners were attached, using the undocumented hidden axes property <b>ScribeLegendListeners</b>:</p>
<pre lang="matlab">
>> legendListener = get(gca,'ScribeLegendListeners')
legendListener =
        fontname: [1x1 handle.listener]
        fontsize: [1x1 handle.listener]
      fontweight: [1x1 handle.listener]
       fontangle: [1x1 handle.listener]
       linewidth: [1x1 handle.listener]
         deleted: [1x1 handle.listener]
    proxydeleted: [1x1 handle.listener]
</pre>
<p>The font size and line positioning were all being redrawn for printing so this was potentially the source of my problem. However I&#8217;d not looked at a <i><b>handle.listener</b></i> before, so a little further digging was required:</p>
<pre lang="matlab">
K>> get(legendListener.fontname)
      SourceObject: [1x1 schema.prop]
         Container: [1x1 axes]
         EventType: 'PropertyPostSet'
          Callback: {2x1 cell}
    CallbackTarget: []
           Enabled: 'on'
</pre>
<p>The option <b>Enabled</b> immediately drew my attention, and so the following lines were added to my gridLegend function to switch off these listeners and apply it back to the legend:</p>
<pre lang="matlab">
LL = get(gca,'ScribeLegendListeners');
set(LL.fontname,'enabled','off');
set(LL.fontsize,'enabled','off');
set(LL.fontweight,'enabled','off');
set(LL.fontangle,'enabled','off');
set(LL.linewidth,'enabled','off');
set(gca,'ScribeLegendListeners',LL);
</pre>
<p>Finally allowing me to output the image files with a multi-column legend:<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Printed multi-column legend" src="https://undocumentedmatlab.com/images/Legend4.jpg" title="Printed multi-column legend" width="450" height="363" /><figcaption class="wp-caption-text">Printed multi-column legend</figcaption></figure></center><br />
So my thanks to the contributors on Matlab Central who enabled me to get started on gridLegend and to Yair for collating the many nuggets of information on Undocumented Matlab which allowed me to complete the function and get it posted on Matlab Central.<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Multi-column legend in action" src="https://undocumentedmatlab.com/images/gridLegend.jpg" title="Multi-column legend in action" width="450" height="300" /><figcaption class="wp-caption-text">Multi-column legend in action</figcaption></figure></center></p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/multi-column-grid-legend">Multi-column (grid) legend</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/multi-line-uitable-column-headers" rel="bookmark" title="Multi-line uitable column headers">Multi-line uitable column headers </a> <small>Matlab uitables can present long column headers in multiple lines, for improved readability. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/transparent-legend" rel="bookmark" title="Transparent legend">Transparent legend </a> <small>Matlab chart legends are opaque be default but can be made semi- or fully transparent. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/plot-legend-customization" rel="bookmark" title="Plot legend customization">Plot legend customization </a> <small>Matlab plot legends and their internal components can be customized using a variety of undocumented properties that are easily accessible. ...</small></li>
<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>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/multi-column-grid-legend/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Accessing plot brushed data</title>
		<link>https://undocumentedmatlab.com/articles/accessing-plot-brushed-data?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=accessing-plot-brushed-data</link>
					<comments>https://undocumentedmatlab.com/articles/accessing-plot-brushed-data#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 06 Oct 2010 18:00:45 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Low risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Callbacks]]></category>
		<category><![CDATA[Menubar]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[scribe]]></category>
		<category><![CDATA[UIInspect]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=1911</guid>

					<description><![CDATA[<p>Plot data brushing can be accessed programmatically using very simple pure-Matlab code</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/accessing-plot-brushed-data">Accessing plot brushed data</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/hidden-hg2-plot-functionality" rel="bookmark" title="Accessing hidden HG2 plot functionality">Accessing hidden HG2 plot functionality </a> <small>In HG2, some of the plot functionality is hidden in undocumented properties. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/draggable-plot-data-tips" rel="bookmark" title="Draggable plot data-tips">Draggable plot data-tips </a> <small>Matlab's standard plot data-tips can be customized to enable dragging, without being limitted to be adjacent to their data-point. ...</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>
<li><a href="https://undocumentedmatlab.com/articles/plot-liminclude-properties" rel="bookmark" title="Plot LimInclude properties">Plot LimInclude properties </a> <small>The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>A few days ago, a reader of the Matlab Desktop blog <a target="_blank" rel="nofollow" href="http://blogs.mathworks.com/desktop/2008/05/12/brush-up-on-your-data/#comment-7364">asked</a> whether it is possible to store plot brushed data in a separate variable for later processing. <a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/techdoc/data_analysis/brh7_p3-1.html#brh7_p3-3">Data Brushing</a>, first introduced in R2008a, enables interactive selection and marking of plot data points. The brushed data can then be stored in a variable using the context (right-click) menu, or the figure&#8217;s Tools/Brushing menu.<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Saving brushed data to a variable" src="https://undocumentedmatlab.com/images/Brushing1b.png" title="Saving brushed data to a variable" width="450" height="325" /><figcaption class="wp-caption-text">Saving brushed data to a variable</figcaption></figure></center><br />
The said reader has specifically wanted programmatic access, rather than interactivity. The official answer is that data brushing was designed to be an interactive tool, and so this cannot be done. However, this has never stopped us before. So off I went to launch my favorite inspection tool, the <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/17935-uiinspect-display-methods-properties-callbacks-of-an-object">UIInspect utility</a> on the figure above (UIInspect will be described in a near-future article), which can be recreated with the following simple code:</p>
<pre lang="matlab">
t=0:0.2:25; plot(t,sin(t),'.-');
% Now brush some data points...
uiinspect(gca);
</pre>
<p><center><figure style="width: 450px" class="wp-caption aligncenter"><a target="_blank" href="/images/Brushing2a.png"><img loading="lazy" decoding="async" alt="UIInspect-ion of a data-brushed plot" src="https://undocumentedmatlab.com/images/Brushing2a.png" title="UIInspect-ion of a data-brushed plot" width="450" height="389" /></a><figcaption class="wp-caption-text">UIInspect-ion of a data-brushed plot (click for details)</figcaption></figure></center><br />
A couple of alternative answers to the reader&#8217;s question were immediately apparent:</p>
<h3 id="data">Directly accessing brushed data</h3>
<p>First, we notice that data brushing added data-brushing context menus, both of which are called <i>BrushSeriesContextMenu</i> (the duplication is an internal Matlab bug, that does not affect usability as far as I can tell).<br />
Also, an invisible scribe overlay axes has been added to hold the new annotations (data brushing is considered an annotation; scribe axes deserve a separate article, which they will indeed get someday).<br />
More importantly for our needs, we see a new <i><b>line</b></i> item called &#8216;Brushing&#8217;, which displays the red lines and data points that we seek. We can now easily get the brushed data using this line&#8217;s <b>XData</b> and <b>YData</b> properties: <u>non</u>-brushed data points simply have NaN values:<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="UIInspect-ion of the data-brushing line" src="https://undocumentedmatlab.com/images/Brushing2b.png" title="UIInspect-ion of the data-brushing line" width="450" height="325" /><figcaption class="wp-caption-text">UIInspect-ion of the data-brushing line</figcaption></figure></center></p>
<pre lang="matlab">
hBrushLine = findall(gca,'tag','Brushing');
brushedData = get(hBrushLine, {'Xdata','Ydata'});
brushedIdx = ~isnan(brushedData{1});
brushedXData = brushedData{1}(brushedIdx);
brushedYData = brushedData{2}(brushedIdx);
% and similarly for ZData in 3D plots
</pre>
<h3 id="callbacks">Accessing brushing callbacks</h3>
<p>Yet another way of approaching the problem is to use the available callback functions built-into the data-brushing functionality. We can access either the <i>BrushSeriesContextMenu</i> or the figure&#8217;s Tools/Brushing menu. I will leave the former (context-menu) approach as an exercise to the reader, and just describe the figure&#8217;s menu approach.<br />
As I have already explained in a <a target="_blank" href="/articles/modifying-default-toolbar-menubar-actions/">dedicated article</a>, figure menu-bar actions are accessible via their handles, and we can retrieve that using a unique tag (well, most of the time &#8211; read that article for details). In our case, the Tools/Brushing/Create-new-variable menu item has the unique tag &#8216;figDataManagerNewVar&#8217;. So let&#8217;s use it:</p>
<pre lang="matlab">
>> hNewVarMenuItem = findall(gcf,'tag','figDataManagerNewVar')
hNewVarMenuItem =
          742.000244140625
>> hNewVarCallback = get(hNewVarMenuItem,'callback')
hNewVarCallback =
    @datamanager.newvar
>> hNewVarCallback(gcf)   % activate the callback
% => set 'ans' as the new variable holding the brushed data
>> ans
ans =
                       6.4         0.116549204850494
                       6.6         0.311541363513379
                       6.8         0.494113351138609
                         7         0.656986598718789
                       7.2         0.793667863849153
                       7.4         0.898708095811627
                       7.6         0.967919672031486
                       7.8         0.998543345374605
                       ...         ...
</pre>
<p>Of course, we could also have gone the hard way, via the scribe axes and the annotations route. For masochistic people like me it could even be a worthwhile challenge. But for all other normal people, why bother when there are such simple alternatives, if we only knew how to find them. 🙂</p>
<h3 id="hg2">Updates for HG2 (R2014b+)</h3>
<p>In HG2 (R2014b+), <code>findall(gca,'tag','Brushing')</code> returns empty data since the way that brushed data is stored has changed. You can access the brushing data using the plot line&#8217;s hidden <b>BrushHandles</b> property, as follows:</p>
<pre lang='matlab'>
hLine = plot(...);
hBrushHandles = hLine.BrushHandles;
hBrushChildrenHandles = hBrushHandles.Children;  % Marker, LineStrip
</pre>
<p>I described the new <code>Marker</code> objects <a href="/articles/plot-markers-transparency-and-color-gradient" target="_blank">here</a>, and <code>LineStrip</code> objects <a href="/articles/customizing-axes-rulers#Axle" target="_blank">here</a>. The brushed vertex data can be retrieved from either of them. For example:</p>
<pre lang='matlab'>
>> hBrushChildrenHandles(1).VertextData
ans =
     1     2     3     4   % X-data of 4 data points
     1     2     3     4   % Y-data of 4 data points
     0     0     0     0   % Z-data of 4 data points
</pre>
<p>If you only need the brushed data points (not the handles for the <code>Markers</code> and <code>LineStrip</code>, you can get them directly from the line handle, using the hidden <b>BrushData</b> property:</p>
<pre lang='matlab'>
>> brushedIdx = logical(hLine.BrushData);  % logical array
>> brushedXData = hLine.XData(brushedIdx);
>> brushedYData = hLine.YData(brushedIdx)
brushedYData =
     1     2     3     4
</pre>
<p><b><u>Addendum 28 Feb, 2018:</u></b> MathWorks posted an official post on Matlab Answers that references the BrushData functionality &#8211; <a href="https://www.mathworks.com/matlabcentral/answers/385226-how-to-use-the-data-brush-tool-to-automatically-save-selected-points-in-multiple-line-plots" rel="nofollow" target="_blank">see here</a>.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/accessing-plot-brushed-data">Accessing plot brushed data</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/hidden-hg2-plot-functionality" rel="bookmark" title="Accessing hidden HG2 plot functionality">Accessing hidden HG2 plot functionality </a> <small>In HG2, some of the plot functionality is hidden in undocumented properties. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/draggable-plot-data-tips" rel="bookmark" title="Draggable plot data-tips">Draggable plot data-tips </a> <small>Matlab's standard plot data-tips can be customized to enable dragging, without being limitted to be adjacent to their data-point. ...</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>
<li><a href="https://undocumentedmatlab.com/articles/plot-liminclude-properties" rel="bookmark" title="Plot LimInclude properties">Plot LimInclude properties </a> <small>The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/accessing-plot-brushed-data/feed</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
		<item>
		<title>Legend &#039;-DynamicLegend&#039; semi-documented feature</title>
		<link>https://undocumentedmatlab.com/articles/legend-semi-documented-feature?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=legend-semi-documented-feature</link>
					<comments>https://undocumentedmatlab.com/articles/legend-semi-documented-feature#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 04 Jun 2009 23:00:22 +0000</pubDate>
				<category><![CDATA[GUI]]></category>
		<category><![CDATA[Listeners]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Semi-documented feature]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[Listener]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[scribe]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=357</guid>

					<description><![CDATA[<p>The built-in Matlab legend function has a very useful semi-documented feature for automatic dynamic update, which is explained here.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/legend-semi-documented-feature">Legend &#039;-DynamicLegend&#039; semi-documented feature</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/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>
<li><a href="https://undocumentedmatlab.com/articles/transparent-legend" rel="bookmark" title="Transparent legend">Transparent legend </a> <small>Matlab chart legends are opaque be default but can be made semi- or fully transparent. ...</small></li>
<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-legend-customization" rel="bookmark" title="Plot legend customization">Plot legend customization </a> <small>Matlab plot legends and their internal components can be customized using a variety of undocumented properties that are easily accessible. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>In one of my projects, I had to build a GUI in which users could interactively add and remove plot lines from an axes. The problem was that the legend needed to be kept in constant sync with the currently-displayed plot lines. This can of course be done programmatically, but a much simpler solution was to use <em><strong>legend</strong></em>&#8216;s semi-documented &#8216;-DynamicLegend&#8217; feature. Here&#8217;s a simple example:</p>
<blockquote>
<pre lang="matlab">
x=0:.01:10;
plot(x, sin(x), 'DisplayName','sin');
legend('-DynamicLegend');
hold all;   % add new plot lines on top of previous ones
plot(x, cos(x), 'DisplayName','cos');
</pre>
</blockquote>
<p>We can see how the dynamic legend automatically keeps in sync with its associated axes contents when plot lines are added/removed, even down to the zoom-box lines&#8230; The legend automatically uses the plot lines &#8216;DisplayName&#8217; property where available, or a standard &#8216;line#&#8217; nametag where not available:<br />
<center><br />
<figure style="width: 300px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" alt="Dynamic legend" src="https://undocumentedmatlab.com/images/legend_animated.gif" title="Dynamic legend" width="300" height="308" /><figcaption class="wp-caption-text">Dynamic legend</figcaption></figure></center><br />
DynamicLegend works by attaching a listener to the axes child addition/deletion callback (actually, it works on the scribe object, which is a large topic for several future posts). It is sometimes necessary to selectively disable the dynamic behavior. For example, in my GUI I needed to plot several event lines which looked alike, and so I only wanted the first line to be added to the legend. To temporarily disable the DynamicLegend listener, do the following:</p>
<blockquote>
<pre lang="matlab">
% Try to disable this axes's legend plot-addition listener
legendAxListener = [];
try
   legendListeners = get(gca,'ScribeLegendListeners');
   legendAxListener = legendListeners.childadded;
   set(legendAxListener,'Enable','off');
catch
   % never mind...
end
% Update the axes - the legend will not be updated
...
% Re-enable the dynamic legend listener
set(legendAxListener,'Enable','on');
</pre>
</blockquote>
<p>Unfortunately, this otherwise-useful DynamicLegend feature throws errors when zooming-in on <em><strong>bar</strong></em> or <em><strong>stairs</strong></em> graphs. This can be replicated by:</p>
<blockquote>
<pre lang="matlab">
figure;
bar(magic(4));  %or: stairs(magic(3),magic(3));
legend('-DynamicLegend');
zoom on;
% Now zoom-in using the mouse to get the errors on the Command Window
</pre>
</blockquote>
<p>The fix: modify %MATLABROOT%\toolbox\matlab\scribe\@scribe\@legend\init.m line #528 as follows:</p>
<blockquote>
<pre lang="matlab">
%old:
str = [str(1:insertindex-1);{newstr};str(insertindex:length(str))];
%new:
if size(str,2)>size(str,1)
    str=[str(1:insertindex-1),{newstr},str(insertindex:length(str))];
else
    str=[str(1:insertindex-1);{newstr};str(insertindex:length(str))];
end
</pre>
</blockquote>
<p>The origin of the bug is that <em><strong>bar</strong></em> and <em><strong>stairs</strong></em> generate <em><strong>hggroup</strong></em> plot-children, which saves the legend strings column-wise rather than the expected row-wise. My fix solves this, but I do not presume this solves all possible problems in all scenarios (please report if you find anything else).<br />
p.s. &#8211; object visibility in the legend can be controlled on an object-by-object basis using the semi-documented <a target="_blank" href="/articles/handle-graphics-behavior#hasbehavior"><i><b>hasbehavior</b></i> function</a>.</p>
<h3 id="Semi-documented">Semi-documented</h3>
<p>The DynamicLegend feature is semi-documented. This means that the feature is explained in a comment within the function (which can be seen via the <strong><em>edit</em></strong>(<span style="color: rgb(160, 32, 240);">&#8216;legend&#8217;</span>) command), that is nonetheless not part of the official help or doc sections. It is an unsupported feature originally intended only for internal Matlab use (which of course doesn&#8217;t mean we can&#8217;t use it). This feature has existed many releases back (Matlab 7.1 for sure, perhaps earlier), so while it may be discontinued in some future Matlab release, it did have a very long life span&#8230; The down side is that it is not supported: I reported the bar/stairs issue back in mid-2007 and so far this has not been addressed (perhaps it will never be). Even my reported workaround in January this year went unanswered (no hard feelings&#8230;).<br />
DynamicLegend is a good example of a useful semi-documented feature. Some other examples, which I may cover in future posts, include <strong><em>text</em></strong>(&#8230;,<span style="color: rgb(160, 32, 240);">&#8216;sc&#8217;</span>), <strong><em>drawnow</em></strong>(<span style="color: rgb(160, 32, 240);">&#8216;discard&#8217;</span>), several options in <strong><em>pan</em></strong> and <strong><em>datacursormode</em></strong> etc. etc.<br />
There are also entire semi-documented functions: many of the uitools (e.g., <strong><em>uitree</em></strong>, <strong><em>uiundo</em></strong>), as well as <strong><em>hgfeval</em></strong> and others.<br />
Have you discovered any useful semi-documented feature or function? If so, then please share your finding in the comments section below.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/legend-semi-documented-feature">Legend &#039;-DynamicLegend&#039; semi-documented feature</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/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>
<li><a href="https://undocumentedmatlab.com/articles/transparent-legend" rel="bookmark" title="Transparent legend">Transparent legend </a> <small>Matlab chart legends are opaque be default but can be made semi- or fully transparent. ...</small></li>
<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-legend-customization" rel="bookmark" title="Plot legend customization">Plot legend customization </a> <small>Matlab plot legends and their internal components can be customized using a variety of undocumented properties that are easily accessible. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/legend-semi-documented-feature/feed</wfw:commentRss>
			<slash:comments>21</slash:comments>
		
		
			</item>
	</channel>
</rss>
