{"id":182,"date":"2007-12-10T10:04:29","date_gmt":"2007-12-10T15:04:29","guid":{"rendered":"https:\/\/blogs.mathworks.com\/desktop\/2007\/12\/10\/focused-on-zooming\/"},"modified":"2016-04-04T09:15:49","modified_gmt":"2016-04-04T13:15:49","slug":"focused-on-zooming","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/community\/2007\/12\/10\/focused-on-zooming\/","title":{"rendered":"Focused on Zooming"},"content":{"rendered":"<i>\r\nI'd like to welcome guest blogger Dan Sternberg from the Plotting and Exploration team. Dan will occasionally be blogging here on the <a href=\"https:\/\/blogs.mathworks.com\/community\/\">Inside the MATLAB Desktop<\/a> blog.\r\n<\/i>\r\n<div class=\"content\">\r\n\r\nZooming in figures has been around forever. There are a couple of neat zoom enhancements, though, that may have snuck in under\r\nyour radar (you didn't read the release notes?!). Between MATLAB 7.0 (R14) and MATLAB 7.3 (R2006b) we added the ability to link\r\ntwo axes, constrain a zoom and customize a zoom. Here are a few examples to help you get started.\r\n\r\n&nbsp;\r\n<h3>Contents<\/h3>\r\n<div>\r\n<ul>\r\n\t<li><a href=\"#1\">Zooming an Axes<\/a><\/li>\r\n\t<li><a href=\"#6\">Linking two Axes<\/a><\/li>\r\n\t<li><a href=\"#9\">Constraining the Zoom<\/a><\/li>\r\n\t<li><a href=\"#10\">Customizing the Zoom<\/a><\/li>\r\n\t<li><a href=\"#15\">Using Zoom in a Custom Application<\/a><\/li>\r\n<\/ul>\r\n<\/div>\r\n<h3>Zooming an Axes<a name=\"1\"><\/a><\/h3>\r\nWe'll start by plotting some data. I'll use one of my favorite data sets, the magic square:\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">ax = axes;\r\np = plot(ax,magic(3));<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_01.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nTo enter zoom mode, I can click on the toolbar button shaped like a magnifying glass.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomIcon.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nAlternatively, I can enter the mode from the command-line.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">zoom <span style=\"color: #a020f0;\">on<\/span>;<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_02.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nFor the purposes of this posting, whenever I wish to zoom, I'll do so programatically, and by a factor of two.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">zoom(2);<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_03.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n<h3>Linking two Axes<a name=\"6\"><\/a><\/h3>\r\nSimply using the zoom tool, I am able to explore a data set that exists in a single axes. You might ask, however,\r\n\r\n\"What if I have two subplots with data that is related? If I zoom in on one plot, can I have the other one follow suit?\"\r\n\r\nThat's an excellent question. I'm glad you asked. Let's create two sequences of data that share a domain, but but live in\r\ndifferent ranges.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">x1 = -2*pi:0.1:2*pi;\r\ny1 = sin(x1);\r\nx2 = -4*pi:0.1:4*pi;\r\ny2 = cos(x2)*100;\r\nax(1) = subplot(1,2,1);\r\nplot(ax(1),x1,y1);\r\nax(2) = subplot(1,2,2);\r\nplot(ax(2),x2,y2);<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_04.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nI can now link these two axes\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">linkaxes(ax,<span style=\"color: #a020f0;\">'x'<\/span>);<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_05.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nFrom this point onwards, if the limits of one x-axis change (perhaps due to a zoom operation), the limits of the second axes\r\nwill follow.\r\n<h3>Constraining the Zoom<a name=\"9\"><\/a><\/h3>\r\nIn addition to linking axes, we can also constrain the zoom direction. For example, I may not want to zoom the y-axis of either\r\none of my subplots.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">zoom <span style=\"color: #a020f0;\">xon<\/span>;\r\nzoom(2);<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_06.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n<h3>Customizing the Zoom<a name=\"10\"><\/a><\/h3>\r\nIt may happen, however, that the two data sets I've plotted do not share a domain or range, but are correlated in some way.\r\nIn this case, I need to do a bit more work to build a relationship. Let's begin by getting the zoom object for the figure.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">hZoom = zoom(gcf);\r\nget(hZoom)<\/pre>\r\n<pre style=\"font-style: oblique;\">      ButtonDownFilter: []\r\n     ActionPreCallback: []\r\n    ActionPostCallback: []\r\n                Enable: 'on'\r\n          FigureHandle: [1x1 figure]\r\n                Motion: 'horizontal'\r\n             Direction: 'in'\r\n      RightClickAction: 'PostContextMenu'\r\n         UIContextMenu: []\r\n\r\n<\/pre>\r\nFrom this object, we can get some information about the state of the figure. For example, we see that zoom mode is on, and\r\nconstrained to be horizontal (x-only).\r\n\r\nThere are also callbacks that may help us further customizing the zoom behavior of these two axes. When the axes were linked,\r\nI lost some information in the second axes. I would much prefer that the second axes zooms twice as much as the first and\r\nthe first zooms half as much as the second. To enforce this relationship, I can use the \"ActionPostCallback\" property of the\r\nobject.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">set(hZoom,<span style=\"color: #a020f0;\">'ActionPostCallback'<\/span>,{@halfZoom,ax});\r\ndbtype <span style=\"color: #a020f0;\">halfZoom.m<\/span><\/pre>\r\n<pre style=\"font-style: oblique;\">1     function halfZoom(fig,evd,ax) %#ok&lt;INUSL&gt;\r\n2     % Zoom one axes by a factor of two from the other:\r\n3     \r\n4     currentAxes = evd.Axes;\r\n5     if currentAxes == ax(1)\r\n6         % If we are zooming the left axes, zoom the right axes by twice as\r\n7         % much:\r\n8         newLim = get(currentAxes,'XLim');\r\n9         set(ax(2),'XLim',newLim*2);\r\n10    else\r\n11        % If we are zooming the right axes, zoom the left axes by half as much:\r\n12        newLim = get(currentAxes,'XLim');\r\n13        set(ax(1),'XLim',newLim\/2);\r\n14    end\r\n<\/pre>\r\nThe event data of the callback tells me which axes I've zoomed in on. From there, I can obtain the axes limits and perform\r\nthe necessary calculations to enforce this relationship.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">linkaxes(ax,<span style=\"color: #a020f0;\">'off'<\/span>);\r\nset(ax,<span style=\"color: #a020f0;\">'XLimMode'<\/span>,<span style=\"color: #a020f0;\">'auto'<\/span>);\r\nzoom(2);<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_07.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nUsing the zoom object, I am also able to prevent an axes from being zoomed or have it only zoom in a particular direction.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">setAllowAxesZoom(hZoom,ax,false);<\/pre>\r\nAt this point, there will be no change to the figure if I attempt to zoom in either axes.\r\n<h3>Using Zoom in a Custom Application<a name=\"15\"><\/a><\/h3>\r\nUsing the zoom object, it is now possible to take advantage of zooming behavior in a custom application. For example, we can\r\nconstruct a figure containing an overview axes. Whenever I zoom in on the main axes, I am able to see where I am in my data.\r\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">overviewPlot(gcf,magic(3));\r\nset(gcf,<span style=\"color: #a020f0;\">'Color'<\/span>,<span style=\"color: #a020f0;\">'w'<\/span>);\r\nzoom <span style=\"color: #a020f0;\">on<\/span>;\r\nzoom(2);<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/desktop\/dan_sternberg_zoom_post\/zoomPost_08.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nThe code to the \"overviewPlot\" function can be found on the File Exchange <a title=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectType=file&amp;objectId=17599 (link no longer works)\">here<\/a>.\r\n\r\nSimilar features exist for the \"pan\" and \"rotate3d\" functions. What sorts of customizations would you like to be able to\r\naccomplish using these tools?\r\n\r\nHere's a video that demonstrates how to use the overviewPlot function. Thanks to Doug (of <a href=\"https:\/\/blogs.mathworks.com\/pick\/\">Doug's Pick of the Week<\/a>) for recording this.\r\n<div align=\"center\"><embed src=\"https:\/\/blogs.mathworks.com\/images\/pick\/FlashVideos\/Others\/FlowPlayer.swf?config=%7Bembedded%3Atrue%2CplayList%3A%5B%7Burl%3A%27OverviewPlot%2Eflv%27%7D%5D%2CbaseURL%3A%27http%3A%2F%2Fblogs%2Emathworks%2Ecom%2Fimages%2Fpick%2FFlashVideos%2FOthers%27%2CsplashImageFile%3A%27OverviewPlot%2Ejpg%27%2Cloop%3Afalse%2CinitialScale%3A%27fit%27%2CshowFullScreenButton%3Afalse%2CautoBuffering%3Afalse%2CmenuItems%3A%5Bfalse%2Cfalse%2Cfalse%2Cfalse%2Cfalse%2Ctrue%5D%2CautoPlay%3Afalse%7D\" type=\"application\/x-shockwave-flash\" width=\"500\" height=\"400\"><\/embed><\/div>\r\n<i>\r\n-by Dan Sternberg, The MathWorks\r\n\r\nThis blog entry was written using the MATLAB publishing feature.\r\n<\/i>\r\n\r\n<script>\/\/ <![CDATA[\r\nfunction grabCode_b72229c17d354f4095c12c71568ec06c() {\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='b72229c17d354f4095c12c71568ec06c ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' b72229c17d354f4095c12c71568ec06c';\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        author = 'Dan Sternberg';\r\n        copyright = 'Copyright 2007 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('\r\n\r\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\r\n\r\n\r\n\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }\r\n\/\/ ]]><\/script>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\">\r\n<a><span style=\"font-size: x-small; font-style: italic;\">Get\r\nthe MATLAB code\r\n<noscript>(requires JavaScript)<\/noscript><\/span><\/a>\r\n\r\nPublished with MATLAB\u00ae 7.5<\/p>\r\n\r\n<\/div>\r\n<!--\r\nb72229c17d354f4095c12c71568ec06c ##### SOURCE BEGIN #####\r\n%% On the Zooming of Figures\r\n% Zooming in figures has been around forever. There are a couple of neat\r\n% zoom enhancements, though, that may have snuck in under your radar (you\r\n% didn't read the release notes?!). Between MATLAB 7.0 (R14) and\r\n% MATLAB 7.3 (R2006b) we added the ability link two axes, constrain a zoom\r\n% and customize a zoom. Here are a few examples to help you get started.\r\n\r\n%% Zooming an Axes\r\n% We'll start by plotting some data. I'll use one of my favorite data sets,\r\n% the magic square:\r\nax = axes;\r\np = plot(ax,magic(3));\r\n\r\n%%\r\n% To enter zoom mode, I can click on the toolbar button shaped like\r\n% a magnifying glass.\r\n%%\r\n% <<zoomIcon.png>>\r\n%%\r\n% Alternatively, I can enter the mode from the command-line.\r\nzoom on;\r\n%%\r\n% For the purposes of this posting, whenever I wish to zoom, I'll do so\r\n% programatically, and by a factor of two.\r\nzoom(2);\r\n\r\n%% Linking two Axes\r\n% Simply using the zoom tool, I am able to explore a data set that exists\r\n% in a single axes. You might ask, however,\r\n%\r\n% \"What if I have two subplots with data that is related? If I zoom in on\r\n% one plot, can I have the other one follow suit?\"\r\n%\r\n% That's an excellent question. I'm glad you asked. Let's create two\r\n% sequences of data that share a domain, but but live in different\r\n% ranges.\r\nx1 = -2*pi:0.1:2*pi;\r\ny1 = sin(x1);\r\nx2 = -4*pi:0.1:4*pi;\r\ny2 = cos(x2)*100;\r\nax(1) = subplot(1,2,1);\r\nplot(ax(1),x1,y1);\r\nax(2) = subplot(1,2,2);\r\nplot(ax(2),x2,y2);\r\n%%\r\n% I can now link these two axes\r\nlinkaxes(ax,'x');\r\n%%\r\n% From this point onwards, if the limits of one x-axis change (perhaps\r\n% due to a zoom operation), the limits of the second axes will follow.\r\n\r\n%% Constraining the Zoom\r\n% In addition to linking axes, we can also constrain the zoom direction.\r\n% For example, I may not want to zoom the y-axis of either one of my\r\n% subplots.\r\nzoom xon;\r\nzoom(2);\r\n\r\n%% Customizing the Zoom\r\n% It may happen, however, that the two data sets I've plotted do not share\r\n% a domain or range, but are correlated in some way. In this case, I need\r\n% to do a bit more work to build a relationship. Let's begin by getting the\r\n% zoom object for the figure.\r\nhZoom = zoom(gcf);\r\nget(hZoom)\r\n%%\r\n% From this object, we can get some information about the state of the\r\n% figure. For example, we see that zoom mode is on, and constrained to be\r\n% horizontal (x-only).\r\n%\r\n% There are also callbacks that may help us further customizing the zoom\r\n% behavior of these two axes. When the axes were linked, I lost some\r\n% information in the second axes. I would much prefer that the second axes\r\n% zooms twice as much as the first and the first zooms half as much as the\r\n% second. To enforce this relationship, I can use the \"ActionPostCallback\"\r\n% property of the object.\r\nset(hZoom,'ActionPostCallback',{@halfZoom,ax});\r\ndbtype halfZoom.m\r\n%%\r\n% The event data of the callback tells me which axes I've zoomed in on.\r\n% From there, I can obtain the axes limits and perform the necessary\r\n% calculations to enforce this relationship.\r\nlinkaxes(ax,'off');\r\nset(ax,'XLimMode','auto');\r\nzoom(2);\r\n%%\r\n% Using the zoom object, I am also able to prevent an axes from being\r\n% zoomed or have it only zoom in a particular direction.\r\nsetAllowAxesZoom(hZoom,ax,false);\r\n%%\r\n% At this point, there will be no change to the figure if I attempt to\r\n% zoom in either axes.\r\n\r\n%% Using Zoom in a Custom Application\r\n% Using the zoom object, it is now possible to take advantage of zooming\r\n% behavior in a custom application. For example, we can construct a figure\r\n% containing an overview axes. Whenever I zoom in on the main axes, I am\r\n% able to see where I am in my data.\r\noverviewPlot(gcf,magic(3));\r\nset(gcf,'Color','w');\r\nzoom on;\r\nzoom(2);\r\n%%\r\n% The code to the \"overviewPlot\" function can be found on the File Exchange\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/loadFile.do?objectType=file&objectId=17599 here>.\r\n%%\r\n% Similar  features exist for the \"pan\" and \"rotate3d\" functions. What sorts\r\n% of customizations would you like to be able to accomplish using these\r\n% tools?\r\n##### SOURCE END ##### b72229c17d354f4095c12c71568ec06c\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\nI'd like to welcome guest blogger Dan Sternberg from the Plotting and Exploration team. Dan will occasionally be blogging here on the Inside the MATLAB Desktop blog.\r\n\r\n\r\n\r\nZooming in figures has... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/community\/2007\/12\/10\/focused-on-zooming\/\">read more >><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[12],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/posts\/182"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/comments?post=182"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/posts\/182\/revisions"}],"predecessor-version":[{"id":3450,"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/posts\/182\/revisions\/3450"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/media?parent=182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/categories?post=182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/community\/wp-json\/wp\/v2\/tags?post=182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}