<?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>UDD &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/tag/udd/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Fri, 30 Sep 2022 14:59:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.3</generator>
	<item>
		<title>Setting class property types</title>
		<link>https://undocumentedmatlab.com/articles/setting-class-property-types?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setting-class-property-types</link>
					<comments>https://undocumentedmatlab.com/articles/setting-class-property-types#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Thu, 18 Apr 2013 14:12:06 +0000</pubDate>
				<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[MCOS]]></category>
		<category><![CDATA[Object oriented]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<category><![CDATA[schema.prop]]></category>
		<category><![CDATA[UDD]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=3725</guid>

					<description><![CDATA[<p>Matlab's class properties have a simple and effective mechanism for setting their type.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/setting-class-property-types">Setting class property types</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-class-property-types-2" rel="bookmark" title="Setting class property types &#8211; take 2">Setting class property types &#8211; take 2 </a> <small>R2016a saw the addition of class property types. However, a better alternative has existed for many years. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/handle-object-as-default-class-property-value" rel="bookmark" title="Handle object as default class property value">Handle object as default class property value </a> <small>MCOS property initialization has a documented but unexpected behavior that could cause many bugs in user code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/getting-default-hg-property-values" rel="bookmark" title="Getting default HG property values">Getting default HG property values </a> <small>Matlab has documented how to modify default property values, but not how to get the full list of current defaults. This article explains how to do this. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects" rel="bookmark" title="Types of undocumented Matlab aspects">Types of undocumented Matlab aspects </a> <small>This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>When I wrote about the <a target="_blank" href="/articles/undocumented-classdef-attributes/">undocumented aspects of classdef properties</a> half a year ago, I did not expect to learn of another major undocumented aspect in Matlab&#8217;s class-object system. last month I discovered the additional undocumented classdef Description and DetailedDescription attributes, and updated that article accordingly. But a few days ago I was pleasantly surprised to read Amro&#8217;s <a target="_blank" href="/articles/undocumented-classdef-attributes/#comment-189056">comment</a> about an entirely new and undocumented aspect of Matlab MCOS classes.</p>
<p><a target="_blank" rel="nofollow" href="http://stackoverflow.com/users/97160/amro">Amro</a> is a top contributor on StackOverflow, where he frequently answers questions before I even get any subscription notification about them&#8230; His answers are generally characterized by a deep technical understanding of Matlab, and I&#8217;ve learned quite a lot from him in the past few years. This time was no different.</p>
<p>In a nutshell, Amro found an undocumented way to specify a class object property&#8217;s type, in such a way that would prevent accidental setting to an incompatible value. For example, if we have a class with properties <b>Width</b> and <b>Height</b>, we probably want to restrict their possible values to numbers, to prevent setting a string or struct value.</p>
<p>In UDD classes, we can do this easily by setting the property&#8217;s <b>DataType</b> meta-property. An easy way to do this is by setting the second argument of the <a target="_blank" href="/articles/creating-a-simple-udd-class/"><i><b>schema.prop</b></i> function</a>. A detailed explanation was provided <a target="_blank" href="/articles/udd-properties/">here</a>.</p>
<p>We can still do this today, since UDD classes are still supported, side-by-side with the newer MCOS classes. Unfortunately, MCOS does not provide a <a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/matlab/matlab_oop/defining-properties.html">documented</a> way of specifying the property type as in UDD.</p>
<p>One simple way to prevent unintentional MCOS property updates is to <a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/matlab/matlab_oop/implementing-a-set-get-interface-for-properties.html">override the property&#8217;s <i><b>set</b></i> method</a>. In fact, this was the <a target="_blank" rel="nofollow" href="http://stackoverflow.com/a/7192964/233829">solution</a> of Jonas, another StackOverflow heavyweight:</p>
<pre lang='matlab'>
classdef myClass
   properties
      myProperty = uint16(23); %# specify default value using correct type
   end
   methods
      function obj = set.myProperty(obj,val)
         if ~isa(val,'uint16')
            error('only uint16 values allowed')
         end
         %# assign the value
         obj.myProperty = val;
      end
   end
end
</pre>
<p>But it turns out that there&#8217;s a much cleaner and simpler solution, <a target="_blank" rel="nofollow" href="http://stackoverflow.com/a/15992558/233829">provided</a> by Amro:</p>
<pre lang='matlab'>
classdef Packet
    properties
        HeaderLength@uint16
        PayloadLength@uint16 = uint16(0);
        PacketType@char
    end
end
</pre>
<p><span id="more-3725"></span><br />
As Amro notes, if you try to set a property with the wrong type, you get an error:</p>
<div class="wp_syntax">
<div class="code">
<pre class="matlab" style="font-family:monospace;">&gt;&gt; p = Packet;
&gt;&gt; p.<span style="">PacketType</span> = <span style="color:#A020F0;">'tcp'</span>;  <span style="color: #228B22;">% ok</span>
&gt;&gt; p.<span style="">HeaderLength</span> = <span style="color: #33f;">100</span>;  <span style="color: #228B22;">% not ok - should be a uint16</span>
<span style="color: #FF0000;">While setting the 'HeaderLength' property of Packet:
Value must be 'uint16'</span>.</pre>
</div>
</div>
<p>This syntax apparently supports all primitive types (<i><b>char, int32, double, struct, cell</b></i> etc.), in addition to any user-defined ones (just use any class name).<br />
Note that setting the type as above seems to override any <i><b>set</b></i> method that may have been specified for the property.</p>
<p>Amro came across this syntax in an internal class in R2013a (<i>toolboxdir(&#8216;matlab&#8217;)/graphics/+graphics/+internal/+figfile/@FigFile/FigFile.m</i>), but it also worked in R2012a, and probably older versions as well&#8230;</p>
<p>I admit there&#8217;s not much original work here by me &#8211; it&#8217;s basically all by Amro (and Donn Shull for the UDD part). But I thought it&#8217;s important enough to bring to the attention of the community.</p>
<p>I love to discover such undocumented treasures by digging in Matlab&#8217;s function. If you ever discover other such buried treasures, please do let me know by email or a comment.</p>
<hr />
<p><b><u>Addendum June 21, 2013</u></b>: As Sebastian Hölz mentioned in his <a href="/articles/setting-class-property-types/#comment-215669">comment</a> below, the general syntax appears to be:</p>
<pre lang='matlab'>
properties
   propName@className dimensionType = initialValue
end
</pre>
<p>where <code>className</code>, <code>dimensionType</code> and <code>initialValue</code> are optional elements:</p>
<ul>
<li><code>className</code> can be any Matlab class/type, such as <code>double</code>, <code>single</code>, or <code>UserClass</code></li>
<li><code>dimensionType</code> can be one of the following terms: <code>scalar</code>, <code>vector</code>, or <code>matrix</code></li>
<li>the property may also be initiated with an <code>initialValue</code> (otherwise it receives a default value, depending on the property class)</li>
</ul>
<hr />
<p><b><u>Addendum August 12, 2014</u></b>: In a related matter, we can limit the values that a property can accept using the <a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/simulink/slref/matlab.system.stringset-class.html">matlab.system.StringSet</a> class of the <a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/simulink/slref/matlab.system-class.html">matlab.System</a> package, as recently <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/answers/138149-autocomplete-of-properties-for-hgsetget-derived-class#answer_144336">discovered</a> by Oleg Komarov (<a target="_blank" rel="nofollow" href="http://www.mathworks.com/help/simulink/ug/limit-property-values-to-a-finite-set-of-strings-1.html">additional details</a>; <a target="_blank" href="/articles/class-object-tab-completion-and-improper-field-names">additional aspects of class property tab-completion</a>):</p>
<pre lang='matlab'>
classdef foo < matlab.System
    properties
        Coordinates
    end
    properties(Hidden,Transient)
        CoordinatesSet = matlab.system.StringSet({'north','south','east','west'});
    end
end
</pre>
<p><center><img decoding="async" alt="restricting Matlab property values" src="https://www.mathworks.com/matlabcentral/answers/uploaded_files/15194/Capture.PNG" title="restricting Matlab property values" width="309" height="129"/></center></p>
<hr />
<p><b><u>Addendum April 8, 2015</u></b>: As reported by Martin A. <a target="_blank" href="/articles/plot-legend-title#comment-347508">here</a> and also <a target="_blank" href="/articles/setting-class-property-types#comment-343150">below</a>, R2015a has apparently added the new (and hidden) <em>Type</em> property to the <em>meta.property</em> class and the <em>InputTypes</em> and <em>OutputTypes</em> properties to the the <em>meta.method</em> class. This enables specifying and querying the types of properties as well as method inputs/outputs. For example:</p>
<pre lang="matlab">
mc = ?matlab.graphics.axis.Axes;
mc.PropertyList(1).Name % Camera
mc.PropertyList(1).Type % matlab.graphics.axis.camera.Camera
mc.MethodList(49).Name % addlistener
mc.MethodList(49).InputNames % [sources, propertyname, eventname, callback]
mc.MethodList(49).InputTypes % [handle, asciiString, char vector, function_handle scalar]
</pre>
<hr />
<p><b><u>Addendum November 11, 2015</u></b>: <a href="/articles/setting-class-property-types#comment-362420">Apparently</a>, when using the <code>@double</code> syntax, Matlab only allows the property to receive real values. In order to enable complex values, we can also add the undocumented "complex" attribute. Note that we have to enter the dimensionality (scalar/vector/matrix) first, since "complex" is not accepted as a valid dimensionality value. For example:</p>
<pre lang='matlab' highlight='4,11'>
% This is ok:
classdef foo
    properties
        bar@double scalar complex = 1 + 2i
    end
end
% This causes an error:
classdef foo
    properties
        bar@double complex = 1 + 2i
    end
end
</pre>
<hr />
<p><b><u>Addendum April 28, 2016</u></b>: Matlab R2016a now has a similar documented functionality. However, I feel that there are important drawbacks to the new functionality compared to the one presented here. Read the <a href="/articles/setting-class-property-types-2" target="_blank">full discussion about this</a>.<br />
The new (documented) syntax automatically type-casts the data to the specified data type, were possible, something that the undocumented (@) syntax presented above does not. In other words, the undocumented syntax is stricter and expects the data to be exactly the specified data type, without attempting any type-casting. As <a href="/articles/setting-class-property-types-2#comment-375230" target="_blank">reported by Martin Afanasjew</a>, we can add the <code>property</code> attribute to the data type to replicate the new syntax's automatic type-casting:</p>
<pre lang="matlab" highlight='4'>
classdef foo
    properties
        prop1@char = 'A'  % will only accept char inputs, not numeric values
        prop2@char property = 65  % will automatically type-cast: 65 will be converted to 'A'
    end
end
</pre>
<hr />
<p><b><u>Addendum September 30, 2022</u></b>: Matlab R2022a has made the legacy @ syntax unsupported, displaying an error message about it in the Matlab Editor, and generating a run-time error if you try to use a class that uses this syntax.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/setting-class-property-types">Setting class property types</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-class-property-types-2" rel="bookmark" title="Setting class property types &#8211; take 2">Setting class property types &#8211; take 2 </a> <small>R2016a saw the addition of class property types. However, a better alternative has existed for many years. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/handle-object-as-default-class-property-value" rel="bookmark" title="Handle object as default class property value">Handle object as default class property value </a> <small>MCOS property initialization has a documented but unexpected behavior that could cause many bugs in user code. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/getting-default-hg-property-values" rel="bookmark" title="Getting default HG property values">Getting default HG property values </a> <small>Matlab has documented how to modify default property values, but not how to get the full list of current defaults. This article explains how to do this. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects" rel="bookmark" title="Types of undocumented Matlab aspects">Types of undocumented Matlab aspects </a> <small>This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/setting-class-property-types/feed</wfw:commentRss>
			<slash:comments>41</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>
	</channel>
</rss>
