<?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>BeanAdapter &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/tag/beanadapter/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Wed, 18 Nov 2015 18:00:55 +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>Customizing contour plots</title>
		<link>https://undocumentedmatlab.com/articles/customizing-contour-plots?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-contour-plots</link>
					<comments>https://undocumentedmatlab.com/articles/customizing-contour-plots#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 18 Nov 2015 18:00:55 +0000</pubDate>
				<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Hidden property]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[Stock Matlab function]]></category>
		<category><![CDATA[BeanAdapter]]></category>
		<category><![CDATA[HG2]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=6075</guid>

					<description><![CDATA[<p>Contour labels, lines and fill patches can easily be customized in Matlab HG2. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-contour-plots">Customizing contour plots</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>Matlab contour labels' color and font can easily be customized. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part-2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>The contour lines of 3D Matlab plot can be customized in many different ways. This is the 2nd article on this issue. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-histogram-plots" rel="bookmark" title="Customizing histogram plots">Customizing histogram plots </a> <small>Basic bar charts and histogram plots can be customized in important aspects. ...</small></li>
<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>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p>One of my clients asked me last week whether it is possible to access and customize individual contour lines and labels in HG2 (Matlab&#8217;s new graphics system, R2014+). Today&#8217;s post will discuss how this could indeed be done.<br />
<figure style="width: 404px" class="wp-caption alignright"><img fetchpriority="high" decoding="async" alt="Matlab contour plot" src="https://undocumentedmatlab.com/images/contour.gif" title="Matlab contour plot" width="404" height="307" /><figcaption class="wp-caption-text">Matlab contour plot</figcaption></figure> In HG1 (R2014a and earlier), contour handles were simple <code>hggroup</code> objects that incorporated <code>text</code> and <code>patch</code> child handles. The contour labels, lines and fill patches could easily be accessed via these child handles (contour lines and fills use the same patch object: the lines are simply the patch edges; fills are their faces). The lines could then be customized, the label strings changed, and the patch faces (fills) recolored:</p>
<pre lang='matlab'>
[X,Y,Z] = peaks;
[C,hContour] = contour(X,Y,Z,20, 'ShowText','on');
hChildren = get(hContour, 'Children');
set(hChildren(1), 'String','Yair', 'Color','b');  % 1st text (contour label)
set(hChildren(end), 'EdgeColor',[0,1,1]);         % last patch (contour line)
</pre>
<p>The problem is that in HG2 (R2014b onward), <i><b>contour</b></i> (and its sibling functions, <i><b>contourf</b></i> etc.) return a graphic object that has no accessible children. In other words, <code>hContour.Children</code> returns an empty array:</p>
<pre lang='matlab'>
>> hContour.Children
ans =
  0x0 empty GraphicsPlaceholder array.
>> allchild(hContour)
ans =
  0x0 empty GraphicsPlaceholder array.
>> isempty(hContour.Children)
ans =
     1
</pre>
<p>So how then can we access the internal contour patches and labels?<br />
<span id="more-6075"></span></p>
<h3 id="hg2">HG2&#8217;s contour object&#8217;s hidden properties</h3>
<p>Skipping several fruitless dead-ends, it turns out that in HG2 the text labels, lines and fills are stored in undocumented hidden properties called <b>TextPrims</b>, <b>EdgePrims</b> and (surprise, surprise) <b>FacePrims</b>, which hold corresponding arrays of <code>matlab.graphics.primitive.world.Text</code>, <code>matlab.graphics.primitive.world.LineStrip</code> and <code>matlab.graphics.primitive.world.TriangleStrip</code> object handles (the <i><b>drawnow</b></i> part is also apparently very important, otherwise you might get errors due to the Prim objects not being ready by the time the code is reached):</p>
<pre lang='matlab'>
>> drawnow;  % very important!
>> hContour.TextPrims  % row array of Text objects
ans =
  1x41 Text array:
  Columns 1 through 14
    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text
  Columns 15 through 28
    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text
  Columns 29 through 41
    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text    Text
>> hContour.EdgePrims  % column array of LineStrip objects
ans =
  20x1 LineStrip array:
  ineStrip
  LineStrip
  LineStrip
  ...
>> hContour.FacePrims  % column array of TriangleStrip objects (empty if no fill)
ans =
  0x0 empty TriangleStrip array.
</pre>
<p>We can now access and customize the individual contour lines, labels and fills:</p>
<pre lang='matlab'>
hContour.TextPrims(4).String = 'Dani';
hContour.TextPrims(7).Visible = 'off';
hContour.TextPrims(9).VertexData = single([-1.3; 0.5; 0]);  % Label location in data units
hContour.EdgePrims(2).ColorData = uint8([0;255;255;255]);  % opaque cyan
hContour.EdgePrims(5).Visible = 'off';
</pre>
<p>Note that the <code>LineStrip</code> objects here are the same as those used for the axes Axles, <a target="_blank" href="/articles/customizing-axes-rulers#Axle">which I described</a> a few months ago. Any customization that we could do to the axle <code>LineStrip</code>s can also be applied to contour <code>LineStrip</code>s, and vice versa.<br />
For example, to achieve the appearance of a <a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Topographic_map">topographic map</a>, we might want to modify some contour lines to use dotted <b>LineStyle</b> and other lines to appear bold by having larger <b>LineWidth</b>. Similarly, we may wish to hide some labels (by setting their <b>Visible</b> property to &#8216;off&#8217;) and make other labels bold (by setting their <b>Font.Weight</b> property to &#8216;bold&#8217;). There are really numerous customization possibilities here.<br />
Here is a listing of the standard (non-hidden) properties exposed by these objects:</p>
<pre lang='matlab'>
>> get(hContour.TextPrims(1))
        BackgroundColor: []
              ColorData: []
              EdgeColor: []
                   Font: [1x1 matlab.graphics.general.Font]
          FontSmoothing: 'on'
       HandleVisibility: 'on'
                HitTest: 'off'
    HorizontalAlignment: 'center'
            Interpreter: 'none'
                  Layer: 'middle'
              LineStyle: 'solid'
              LineWidth: 1
                 Margin: 1
                 Parent: [1x1 Contour]
          PickableParts: 'visible'
               Rotation: 7.24591082075548
                 String: '-5.1541'
          StringBinding: 'copy'
             VertexData: [3x1 single]
      VerticalAlignment: 'middle'
                Visible: 'on'
>> get(hContour.EdgePrims(1))
          AlignVertexCenters: 'off'
             AmbientStrength: 0.3
                ColorBinding: 'object'
                   ColorData: [4x1 uint8]
                   ColorType: 'truecolor'
             DiffuseStrength: 0.6
            HandleVisibility: 'on'
                     HitTest: 'off'
                       Layer: 'middle'
                     LineCap: 'none'
                    LineJoin: 'round'
                   LineStyle: 'solid'
                   LineWidth: 0.5
               NormalBinding: 'none'
                  NormalData: []
                      Parent: [1x1 Contour]
               PickableParts: 'visible'
    SpecularColorReflectance: 1
            SpecularExponent: 10
            SpecularStrength: 0.9
                   StripData: [1 18]
                     Texture: [0x0 GraphicsPlaceholder]
                  VertexData: [3x17 single]
               VertexIndices: []
                     Visible: 'on'
       WideLineRenderingHint: 'software'
>> get(hContour.FacePrims(1))
             AmbientStrength: 0.3
             BackFaceCulling: 'none'
                ColorBinding: 'object'
                   ColorData: [4x1 uint8]
                   ColorType: 'truecolor'
             DiffuseStrength: 0.6
            HandleVisibility: 'on'
                     HitTest: 'off'
                       Layer: 'middle'
               NormalBinding: 'none'
                  NormalData: []
                      Parent: [1x1 Contour]
               PickableParts: 'visible'
    SpecularColorReflectance: 1
            SpecularExponent: 10
            SpecularStrength: 0.9
                   StripData: [1 4 13 16 33 37 41 44 51 54 61 64 71 74 87 91 94 103]
                     Texture: [0x0 GraphicsPlaceholder]
            TwoSidedLighting: 'off'
                  VertexData: [3x102 single]
               VertexIndices: []
                     Visible: 'on'
</pre>
<p>But how did I know these properties existed? The easiest way in this case would be to use my <a target="_blank" href="/articles/getundoc-get-undocumented-object-properties"><i><b>getundoc</b></i> utility</a>, but we could also use my <a target="_blank" href="/articles/uiinspect"><i><b>uiinspect</b></i> utility</a> or even the plain-ol&#8217; <a target="_blank" href="/articles/accessing-private-object-properties"><i><b>struct</b></i> function</a>.<br />
<i>p.s. &#8211; there&#8217;s an alternative way, using the Java bean adapter that is associated with each Matlab graphics object: <code>java(hContour)</code>. Specifically, this object apparent has the public method <code>browseableChildren(java(hContour))</code> which returns the list of all children (in our case, 41 text labels [bean adapters], 20 lines, and a single object holding a <code>ListOfPointsHighlight</code> that corresponds to the regular hidden <b>SelectionHandle</b> property). However, I generally dislike working with the bean adapters, especially when there&#8217;s a much &#8220;cleaner&#8221; way to get these objects, in this case using the regular <b>EdgePrims</b>, <b>FacePrims</b>, <b>TextPrims</b> and <b>SelectionHandle</b> properties. Readers who are interested in Matlab internals can explore the bean adapters using a combination of my <a target="_blank" href="/articles/getundoc-get-undocumented-object-properties"><b>getundoc</b></a> and <a target="_blank" href="/articles/uiinspect"><b>uiinspect</b></a> utilities.</i><br />
So far for the easy part. Now for some more challenging questions:</p>
<h3 id="color">Customizing the color</h3>
<p>First, can we modify the contour fill to have a semi- (or fully-) transparent fill color? &#8211; indeed we can:</p>
<pre lang='matlab'>
[~, hContour] = contourf(peaks(20), 10);
drawnow;  % this is important, to ensure that FacePrims is ready in the next line!
hFills = hContour.FacePrims;  % array of TriangleStrip objects
[hFills.ColorType] = deal('truecoloralpha');  % default = 'truecolor'
for idx = 1 : numel(hFills)
   hFills(idx).ColorData(4) = 150;   % default=255
end
</pre>
<p><center><figure style="width: 420px" class="wp-caption aligncenter"><img decoding="async" alt="Contour plot in HG2, with and without transparency" src="https://undocumentedmatlab.com/images/hg2-contourf-animated.gif" title="Contour plot in HG2, with and without transparency" width="420" height="300" /><figcaption class="wp-caption-text">Contour plot in HG2, with and without transparency</figcaption></figure></center><br />
Similar transparency effects can also be applied to the <code>LineStrip</code> and <code>Text</code> objects. A discussion of the various combinations of acceptable color properties <a target="_blank" href="/articles/customizing-axes-rulers#Axle">can be found here</a>.</p>
<h3 id="mouse">Mouse clicks</h3>
<p>Next, how can we set a custom context-menu for individual labels and contour lines?<br />
Unfortunately, <code>Text</code>, <code>LineStrip</code> and <code>TriangleStrip</code> objects do not posses a <b>ButtonDownFcn</b> or <b>UIContextMenu</b> property, not even hidden. I tried searching in the internal/undocumented properties, but nothing came up.</p>
<h5 id="mouse1">Mouse click solution #1</h5>
<p>So the next logical step would be to trap the mouse-click event at the contour object level. We cannot simply click the contour and check the clicked object because that would just give us the <code>hContour</code> object handle rather than the individual <code>Text</code> or <code>LineStrip</code>. So the idea would be to set <code>hContour.HitTest='off'</code>, in the hope that the mouse click would be registered on the graphic object directly beneath the mouse cursor, namely the label or contour line. It turns out that the labels&#8217; and lines&#8217; <b>HitTest</b> property is &#8216;off&#8217; by default, so, we also need to set them all to &#8216;on&#8217;:</p>
<pre lang='matlab'>
hContour.HitTest = 'off';
[hContour.TextPrims.HitTest] = deal('on');
[hContour.EdgePrims.HitTest] = deal('on');
[hContour.FacePrims.HitTest] = deal('on');
hContour.ButtonDownFcn = @(h,e)disp(struct(e));
</pre>
<p>This seemed simple enough, but failed spectacularly: it turns out that because <code>hContour.HitTest='off'</code>, mouse clicks are not registered on this objects, and on the other hand we cannot set the <b>ButtonDownFcn</b> on the primitive objects because they don&#8217;t have a <b>ButtonDownFcn</b> property!<br />
Who said life is easy?<br />
One workaround is to set the figure&#8217;s <b>WindowButtonDownFcn</b> property:</p>
<pre lang='matlab'>set(gcf, 'WindowButtonDownFcn', @myMouseClickCallback);</pre>
<p>Now, inside your <code>myMouseClickCallback</code> function you can check the clicked object. We could use the undocumented builtin <a target="_blank" rel="nofollow" href="https://www.mathworks.com/matlabcentral/newsreader/view_thread/239883#613421"><i><b>hittest</b>(hFig)</i> function</a> to see which object was clicked. Alternatively, we could use the callback <code>eventData</code>&#8216;s undocumented <b>HitObject</b>/<b>HitPrimitive</b> properties (this variant does not require the <b>HitTest</b> property modifications above):</p>
<pre lang='matlab'>
function myMouseClickCallback(hFig, eventData)
   hitPrimitive = hittest(hFig);  % undocumented function
   hitObject    = eventData.HitObject;     % undocumented property => returns a Contour object (=hContour)
   hitPrimitive = eventData.HitPrimitive;  % undocumented property => returns a Text or LineStrip object
   hitPoint     = eventData.Point;         % undocumented property => returns [x,y] pixels from figure's bottom-left corner
   if strcmpi(hFig.SelectionType,'alt')  % right-click
      if isa(hitPrimitive, 'matlab.graphics.primitive.world.Text')  % label
         displayTextContextMenu(hitPrimitive, hitPoint)
      elseif isa(hitPrimitive, 'matlab.graphics.primitive.world.LineStrip')  % contour line
         displayLineContextMenu(hitPrimitive, hitPoint)
      elseif isa(hitPrimitive, 'matlab.graphics.primitive.world.TriangleStrip')  % contour fill
         displayFillContextMenu(hitPrimitive, hitPoint)
      else
         ...
      end
   end
end
</pre>
<h5 id="mouse2">Mouse click solution #2</h5>
<p>A totally different solution is to keep the default <code>hContour.HitTest='on'</code> (and the primitives&#8217; as &#8216;off&#8217;) and simply query the contour object&#8217;s <b>ButtonDownFcn</b> callback&#8217;s <code>eventData</code>&#8216;s undocumented <b>Primitive</b> property:</p>
<pre lang='matlab'>hContour.ButtonDownFcn = @myMouseClickCallback;</pre>
<p>And in the callback function:</p>
<pre lang='matlab'>
function myMouseClickCallback(hContour, eventData)
   hitPrimitive = eventData.Primitive;  % undocumented property => returns a Text or LineStrip object
   hitPoint     = eventData.IntersectionPoint;  % [x,y,z] in data units
   hFig = ancestor(hContour, 'figure');
   if strcmpi(hFig.SelectionType,'alt')  % right-click
      if isa(hitPrimitive, 'matlab.graphics.primitive.world.Text')  % label
         displayTextContextMenu(hitPrimitive, hitPoint)
      elseif isa(hitPrimitive, 'matlab.graphics.primitive.world.LineStrip')  % contour line
         displayLineContextMenu(hitPrimitive, hitPoint)
      elseif isa(hitPrimitive, 'matlab.graphics.primitive.world.TriangleStrip')  % contour fill
         displayFillContextMenu(hitPrimitive, hitPoint)
      else
         ...
      end
   end
end
</pre>
<p><a target="_blank" href="/articles/adding-context-menu-to-uitree">This article</a> should be a good start in how to code the <code>displayTextContextMenu</code> etc. functions to display a context menu.</p>
<h3 id="reset">Customizations reset</h3>
<p>Finally, there are apparently numerous things that cause our customized labels and lines to reset to their default appearance: resizing, updating contour properties etc. To update the labels in all these cases in one place, simply listen to the undocumented <a target="_blank" href="/articles/undocumented-hg2-graphics-events"><code>MarkedClean</code> event</a>:</p>
<pre lang='matlab'>addlistener(hContour, 'MarkedClean', @updateLabels);</pre>
<p>Where <code>updateLabels</code> is a function were you set all the new labels.</p>
<h3 id="future">Prediction about forward compatibility</h3>
<p>I am marking this article as &#8220;<a target="_blank" href="/articles/category/presumed-future-risk/high-risk-of-breaking-in-future-versions">High risk of breaking in future Matlab versions</a>&#8220;, not because of the basic functionality (being important enough I don&#8217;t presume it will go away anytime soon) but because of the property names: <b>TextPrims</b>, <b>EdgePrims</b> and <b>FacePrims</b> don&#8217;t seem to be very user-friendly property names. So far MathWorks has been very diligent in making its object properties have meaningful names, and so I assume that when the time comes to expose these properties, they will be renamed (perhaps to <b>TextHandles</b>, <b>EdgeHandles</b> and <b>FaceHandles</b>, or perhaps <b>LabelHandles</b>, <b>LineHandles</b> and <b>FillHandles</b>). For this reason, even if you find out in some future Matlab release that <b>TextPrims</b>, <b>EdgePrims</b> and <b>FacePrims</b> don&#8217;t exist, perhaps they still exist and simply have different names.<br />
<u><b>Addendum November 11, 2017</b></u>: The <b>TextPrims</b>, <b>EdgePrims</b> and <b>FacePrims</b> properties have still not changed their names and functionality. I explained a nice use for them in <a href="/articles/customizing-contour-plots-part2" target="_blank">a followup post</a>, explaining how we can modify the contour labels to have different font sizes and the same colors as their corresponding contour lines.</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/customizing-contour-plots">Customizing contour plots</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>Matlab contour labels' color and font can easily be customized. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-contour-plots-part-2" rel="bookmark" title="Customizing contour plots part 2">Customizing contour plots part 2 </a> <small>The contour lines of 3D Matlab plot can be customized in many different ways. This is the 2nd article on this issue. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-histogram-plots" rel="bookmark" title="Customizing histogram plots">Customizing histogram plots </a> <small>Basic bar charts and histogram plots can be customized in important aspects. ...</small></li>
<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>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/customizing-contour-plots/feed</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
			</item>
	</channel>
</rss>
