"Restore View" limits come from... where?

100 views (last 30 days)
I'm having some difficulty with a plot in Matlab 2018b. After plotting the data, I select the "Zoom In" option from the axes menu on the top-right, and zoom in and out to inspect the data. I later select "Restore View" from the context menu available when using "Zoom In", expecting it to go back to what it was after I plotted the data. However, I end up with a blank white axes with XLim [0 1]. (Legitimate X limits would be along the lines of [7.3705e+05 7.3740e+05].) Manually setting the X limits reveals that my data plots are still there, but well out of view.
My question is: Where is Matlab getting the limits that should be used when performing "Restore View"?
If needed, here's some more detailed information:
I am using a stack of two axes, directly overlaid on top of each other, inside of a graphics panel. The two axes are linked on the X-axis ("linkaxes([a,b],'x');"). The "upper" axes are set to have no background color, and "PickableParts" has been set to none.
  2 Comments
Walter Roberson
Walter Roberson on 1 Mar 2019
It has been a while since I looked at that code. I have a half memory of noting that the portion dealing with restoring from linked axes was a bit messy and looked like it would be prone to error.
I seem to recall that when the plot is rendered in an axes that has a modal behavior manager active on it, that the XLim and YLim properties are stored as UserData (might have been AppData), and that Restore View pulls those values out... at least in the simple non-linked case.
Sean Mahnken
Sean Mahnken on 2 Mar 2019
Thanks, Walter. That is EXACTLY the answer I was looking for.
Recognizing that I may just have to fiddle with it, I'll ask a follow-on question anyway. The AppData structure has two candidates. There is an array called "zoom_zoomOrigAxesLimits", and there is a substructure "matlab_graphics_resetplotview" with an XLim member. Both show [0 1] and would explain why I'm seeing what I'm seeing. Do you happen to know which of the two is referenced by the "Restore View" function(s)?

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 2 Mar 2019
Look in zoom.m function getbounds(), about line 1074. It is axes appdata zoom_zomOrigAxesLimits that it pulls out to make sure you do not zoom out too far.
With you having two axes, then I would worry about the expected axes being the active axes.
  3 Comments
Andrew Landau
Andrew Landau on 26 Jun 2019
Related question-
I'm designing a gui with appdesigner, and want to be able to set the default xlim. It appears that you can set the default xlim for a freestanding axes, but not for an axes within an appdesigner app.
A MWE is as follows:
x = 1:512;
y = rand(1,512);
figure;
plot(x,y);
xlim([1 512]);
If you zoom in then hit the "Restore View" home button, it will go back to xlim([1 512]), even though it doesn't default to that before it is set.
A MWE for the appdesigner:
To make this work you need a file with the classdef code that's larger, then run the following two lines:
test = testAxesLimit; % Create app
ax = returnAx(test); % Return axes
If you zoom in then hit restore view, it will go back to ~xlim([1 550])...
It's a simple issue but I'd love to fix it if possible!
Here's the classdef:
classdef testAxesLimit < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
testAx matlab.ui.control.UIAxes
end
methods (Access = public)
function ax = returnAx(app)
ax = app.testAx;
end
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
x = 1:512;
y = rand(1,512);
plot(app.testAx,x,y);
xlim(app.testAx,[1 512]);
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'UI Figure';
% Create testAx
app.testAx = uiaxes(app.UIFigure);
title(app.testAx, 'Title')
xlabel(app.testAx, 'X')
ylabel(app.testAx, 'Y')
app.testAx.Position = [48 60 536 356];
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = testAxesLimit
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
Walter Roberson
Walter Roberson on 26 Jun 2019
Sorry, I have only looked at the very surface of how appdesigner works.

Sign in to comment.

More Answers (1)

breathi
breathi on 17 May 2021
Edited: breathi on 17 May 2021
Since this thread is in the top search results for linkaxes as well, here is a related article for linkaxes from MathWorks: https://www.mathworks.com/matlabcentral/answers/426098-zoom-auto-doesn-t-work-with-linkaxes-when-data-is-replaced
So for linkaxes, the easiest solution is to restore the auto mode for Lim:
% ax is an Axes array
% link x axes of all plots
linkaxes(ax,'x');
% reset XLimMode back to auto to properly "Restore View" when data is
% exchanged
[ax.XLimMode] = deal('auto');
In other cases, Walter is right. Here some more information.
From my info, "Restore View" finally triggers
resetplotview
which is an internal function. A more common function to restore the view is
zoom out;
For R2021a, the appdata change can be seen in localResetPlotView():
edit(fullfile(matlabroot, 'toolbox', 'matlab', 'graphics', 'resetplotview.m'))
So basically, the standard view of an axes can be found with
getappdata(ax)
And as Walter suggested, look for "zoom_zoomOrigAxesLimits". If it is not set, the axes view has not yet been modified by zoom/pan. Changing the limit property also doesn't set a "Restore View" point.
zoom reset;
resetplotview(ax,'InitializeCurrentView');
% or possibly remove the zoom data fields:
rmappdata(ax, 'zoom_zoomOrigAxesLimits');
rmappdata(ax, 'matlab_graphics_resetplotview');

Categories

Find more on Develop uifigure-Based Apps in Help Center and File Exchange

Tags

Products


Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!