{"id":92,"date":"2014-11-11T08:46:54","date_gmt":"2014-11-11T13:46:54","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics\/?p=92"},"modified":"2016-04-19T09:25:20","modified_gmt":"2016-04-19T13:25:20","slug":"highlighting-parts-of-charts","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics\/2014\/11\/11\/highlighting-parts-of-charts\/","title":{"rendered":"Highlighting Parts of Charts"},"content":{"rendered":"<div class=\"content\"><h3>Highlighting Parts of Charts<\/h3><p>Sometimes you would like change how a chart looks in a way which isn&#8217;t supported by the implementation of the chart. For example, you might want to change the color of one of the bars in a bar chart to highlight it.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/highlightbar.png\" alt=\"\"> <\/p><p>The bar chart currently doesn&#8217;t give you a way to do this. One way which immediately comes to mind is to find and modify the object which the bar chart created to represent that single bar. It turns out that doing this by fiddling around with the bar chart&#8217;s internals is actually not a great approach. There are a couple of reasons for this. Sometimes the charts are doing something which is trickier than it my seem. For example, if the number of bars gets really large, it might combine some of them for performance reasons. In addition, if the chart redraws, it might overwrite your modifications, and you&#8217;ll have to reapply them. Also, the details of a chart&#8217;s internals often change when you get a new release of MATLAB.<\/p><p>A better approach to this sort of problem is actually to create two separate charts. We can then give each of the two charts different attributes. Then we can highlight particular data values by partitioning the data between the two charts.<\/p><p>The easiest way to partition the data is to use the fact that the charts ignore any data values which are set to NaN. For example, we can recreate the picture above like this. First we create an array named ydata.<\/p><pre class=\"codeinput\">rng(0)\r\nydata = rand(1,15);\r\n<\/pre><p>Next we create an array of logicals which is the same size.<\/p><pre class=\"codeinput\">sel = false(size(ydata));\r\n<\/pre><p>We're going to put true into this array anywhere we want a bar to be red.<\/p><pre class=\"codeinput\">sel(9) = true;\r\n<\/pre><p>Now we can use that logical array as a \"mask\" to partition ydata into two copies. One copy has nan where sel is true. The other copy has nan wherever sel if false.<\/p><pre class=\"codeinput\">y1 = ydata;\r\ny1(sel) = nan;\r\n\r\ny2 = ydata;\r\ny2(~sel) = nan;\r\n<\/pre><p>Now we can use hold to create two bar charts from these two arrays.<\/p><pre class=\"codeinput\">figure\r\nh1 = bar(y1);\r\nhold <span class=\"string\">on<\/span>\r\nh2 = bar(y2);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/barexample_01.png\" alt=\"\"> <p>At this point, we can change any of the properties on either of the charts to make them look different. For example, to get the picture above, we&#8217;d set the FaceColor of the second bar to red.<\/p><pre class=\"codeinput\">h2.FaceColor = <span class=\"string\">'red'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/barexample_02.png\" alt=\"\"> <p>But we could change anything. Maybe you're Auric Goldfinger, and you'd like the highlight to look like a big gold bar.<\/p><pre class=\"codeinput\">ax = gca;\r\nh1.FaceColor = ax.ColorOrder(1,:);\r\nh2.FaceColor = ax.ColorOrder(3,:);\r\nh1.BarWidth = .5;\r\nh2.BarWidth = 1;\r\nh2.EdgeColor = <span class=\"string\">'none'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/barexample_03.png\" alt=\"\"> <p>OK, now that we have that basic trick, let&#8217;s go crazy with it. We&#8217;ll build a simple interactive app which lets us click on the bars to change which ones are highlighted. To do that, we&#8217;ll need to listen for clicks and use that to change the contents of the two arrays.<\/p><p>Here&#8217;s a complete implementation.<\/p><pre class=\"language-matlab\"><span class=\"keyword\">function<\/span> highlightable_bar(ydata)\r\n  <span class=\"comment\">% An example of how to use two bar charts to highlight<\/span>\r\n  <span class=\"comment\">% selected values.<\/span>\r\n  <span class=\"comment\">%<\/span>\r\n  <span class=\"comment\">% Create 2 bar charts.<\/span>\r\n  h1 = bar(ydata);\r\n  hold <span class=\"string\">on<\/span>;\r\n  h2 = bar(nan(size(ydata)));\r\n  hold <span class=\"string\">off<\/span>;\r\n  <span class=\"comment\">% You can set whatever properties you like on each of them to make<\/span>\r\n  <span class=\"comment\">% them look as different as you would like.<\/span>\r\n  h2.FaceColor = <span class=\"string\">'red'<\/span>;\r\n  <span class=\"comment\">% Add a button down listener to each bar chart<\/span>\r\n  h1.ButtonDownFcn = @btndwn;\r\n  h2.ButtonDownFcn = @btndwn;\r\n  <span class=\"keyword\">function<\/span> btndwn(~,evd)\r\n    <span class=\"comment\">% Figure out which bar the user clicked on. The eventdata tells us<\/span>\r\n    <span class=\"comment\">% where the mouse was when the click occurred.<\/span>\r\n    x = round(evd.IntersectionPoint(1));\r\n    <span class=\"comment\">% Create 2 YData arrays from the original one. The first<\/span>\r\n    <span class=\"comment\">% has a nan for the selected bar. The second has nans for<\/span>\r\n    <span class=\"comment\">% all of the other bars.<\/span>\r\n    sel = false(size(ydata));\r\n    sel(x) = true;\r\n    h1.YData = ydata;\r\n    h1.YData(sel) = nan;\r\n    h2.YData = ydata;\r\n    h2.YData(~sel) = nan;\r\n  <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><p>The function btndwn will get called every time one of the bars gets clicked on. When that happens, we create new YData arrays for the two bar charts. We do this by updating the entry in the logical array sel which corresponds to the bar which was clicked on. Let's start clicking!<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2014\/barhighlightanimation.gif\" alt=\"\"> <\/p><p>You can use this same technique with other types of charts. For example, check out this contour plot with major &amp; minor contour lines. You can find out how to create this on the doc page <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/examples\/combining-different-visualizations.html\">Combining Different Visualizations<\/a>.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/CombiningVisualizationsExample_05.png\" alt=\"\"> <\/p><p>What can you create using this technique?<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_c6663d35ee764a91bbeb29b109e556a8() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='c6663d35ee764a91bbeb29b109e556a8 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' c6663d35ee764a91bbeb29b109e556a8';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2014 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_c6663d35ee764a91bbeb29b109e556a8()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2014b<br><\/p><\/div><!--\r\nc6663d35ee764a91bbeb29b109e556a8 ##### SOURCE BEGIN #####\r\n%% Highlighting Parts of Charts\r\n% Sometimes you would like change how a chart looks in a way which isn\u00e2\u20ac\u2122t \r\n% supported by the implementation of the chart. For example, you might \r\n% want to change the color of one of the bars in a bar chart to highlight \r\n% it.\r\n%\r\n% <<..\/highlightbar.png>>\r\n%\r\n% The bar chart currently doesn\u00e2\u20ac\u2122t give you a way to do this. One way which \r\n% immediately comes to mind is to find and modify the object which the bar \r\n% chart created to represent that single bar. It turns out that doing this \r\n% by fiddling around with the bar chart\u00e2\u20ac\u2122s internals is actually not a great \r\n% approach. There are a couple of reasons for this. Sometimes the charts \r\n% are doing something which is trickier than it my seem. For example, if \r\n% the number of bars gets really large, it might combine some of them for \r\n% performance reasons. In addition, if the chart redraws, it might overwrite \r\n% your modifications, and you\u00e2\u20ac\u2122ll have to reapply them. Also, the details of \r\n% a chart\u00e2\u20ac\u2122s internals often change when you get a new release of MATLAB.\r\n%\r\n% A better approach to this sort of problem is actually to create two \r\n% separate charts. We can then give each of the two charts different \r\n% attributes. Then we can highlight particular data values by partitioning \r\n% the data between the two charts.\r\n%\r\n% The easiest way to partition the data is to use the fact that the charts \r\n% ignore any data values which are set to NaN. For example, we can recreate\r\n% the picture above like this. First we create an array named ydata.\r\n%\r\nrng(0)\r\nydata = rand(1,15);\r\n\r\n%%\r\n% Next we create an array of logicals which is the same size.\r\n%\r\nsel = false(size(ydata));\r\n\r\n%%\r\n% We're going to put true into this array anywhere we want a bar to be red.\r\n%\r\nsel(9) = true;\r\n\r\n%%\r\n% Now we can use that logical array as a \"mask\" to partition ydata into two\r\n% copies. One copy has nan where sel is true. The other copy has nan\r\n% wherever sel if false.\r\ny1 = ydata;\r\ny1(sel) = nan;\r\n\r\ny2 = ydata;\r\ny2(~sel) = nan;\r\n\r\n%%\r\n% Now we can use hold to create two bar charts from these two arrays.\r\n%\r\nfigure\r\nh1 = bar(y1);\r\nhold on\r\nh2 = bar(y2);\r\n\r\n%%\r\n% At this point, we can change any of the properties on either of the \r\n% charts to make them look different. For example, to get the picture \r\n% above, we\u00e2\u20ac\u2122d set the FaceColor of the second bar to red.\r\n%\r\nh2.FaceColor = 'red';\r\n\r\n%%\r\n% But we could change anything. Maybe you're Auric Goldfinger, and you'd\r\n% like the highlight to look like a big gold bar.\r\nax = gca;\r\nh1.FaceColor = ax.ColorOrder(1,:);\r\nh2.FaceColor = ax.ColorOrder(3,:);\r\nh1.BarWidth = .5;\r\nh2.BarWidth = 1;\r\nh2.EdgeColor = 'none';\r\n\r\n%%\r\n% OK, now that we have that basic trick, let\u00e2\u20ac\u2122s go crazy with it. We\u00e2\u20ac\u2122ll build \r\n% a simple interactive app which lets us click on the bars to change which \r\n% ones are highlighted. To do that, we\u00e2\u20ac\u2122ll need to listen for clicks and use \r\n% that to change the contents of the two arrays.\r\n%\r\n% Here\u00e2\u20ac\u2122s a complete implementation.\r\n%\r\n%   function highlightable_bar(ydata)\r\n%     % An example of how to use two bar charts to highlight\r\n%     % selected values.\r\n%     %\r\n%     % Create 2 bar charts. \r\n%     h1 = bar(ydata);\r\n%     hold on;\r\n%     h2 = bar(nan(size(ydata)));\r\n%     hold off;\r\n%     % You can set whatever properties you like on each of them to make \r\n%     % them look as different as you would like.\r\n%     h2.FaceColor = 'red';\r\n%     % Add a button down listener to each bar chart\r\n%     h1.ButtonDownFcn = @btndwn;\r\n%     h2.ButtonDownFcn = @btndwn;\r\n%     function btndwn(~,evd)\r\n%       % Figure out which bar the user clicked on. The eventdata tells us \r\n%       % where the mouse was when the click occurred.\r\n%       x = round(evd.IntersectionPoint(1));\r\n%       % Create 2 YData arrays from the original one. The first\r\n%       % has a nan for the selected bar. The second has nans for\r\n%       % all of the other bars.\r\n%       sel = false(size(ydata));\r\n%       sel(x) = true;\r\n%       h1.YData = ydata;\r\n%       h1.YData(sel) = nan;\r\n%       h2.YData = ydata;\r\n%       h2.YData(~sel) = nan;\r\n%     end\r\n%   end\r\n%%\r\n% The function btndwn will get called every time one of the bars gets \r\n% clicked on. When that happens, we create new YData arrays for the two bar \r\n% charts. We do this by updating the entry in the logical array sel which \r\n% corresponds to the bar which was clicked on. Let's start clicking!\r\n%\r\n% <<..\/barhighlightanimation.gif>>\r\n%\r\n% You can use this same technique with other types of charts. For example,\r\n% check out this contour plot with major & minor contour lines. You can find \r\n% out how to create this on the doc page \r\n% <https:\/\/www.mathworks.com\/help\/matlab\/examples\/combining-different-visualizations.html Combining Different Visualizations>.\r\n%\r\n% <<https:\/\/www.mathworks.com\/help\/examples\/matlab_product\/CombiningVisualizationsExample_05.png>>\r\n%\r\n% What can you create using this technique?\r\n%\r\n\r\n\r\n\r\n\r\n##### SOURCE END ##### c6663d35ee764a91bbeb29b109e556a8\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/feature_image\/barhighlightanimation.gif\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>Highlighting Parts of ChartsSometimes you would like change how a chart looks in a way which isn&#8217;t supported by the implementation of the chart. For example, you might want to change the color... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics\/2014\/11\/11\/highlighting-parts-of-charts\/\">read more >><\/a><\/p>","protected":false},"author":89,"featured_media":96,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[7,9],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/92"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/users\/89"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/comments?post=92"}],"version-history":[{"count":8,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/92\/revisions"}],"predecessor-version":[{"id":474,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/92\/revisions\/474"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media\/96"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media?parent=92"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/categories?post=92"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/tags?post=92"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}