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

69 ビュー (過去 30 日間)
Sean Mahnken
Sean Mahnken 2019 年 3 月 1 日
編集済み: breathi 2021 年 5 月 17 日
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 件のコメント
Walter Roberson
Walter Roberson 2019 年 3 月 1 日
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 2019 年 3 月 2 日
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)?

サインインしてコメントする。

採用された回答

Walter Roberson
Walter Roberson 2019 年 3 月 2 日
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 件のコメント
Andrew Landau
Andrew Landau 2019 年 6 月 26 日
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 2019 年 6 月 26 日
Sorry, I have only looked at the very surface of how appdesigner works.

サインインしてコメントする。

その他の回答 (1 件)

breathi
breathi 2021 年 5 月 17 日
編集済み: breathi 2021 年 5 月 17 日
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');

カテゴリ

Help Center および File ExchangeDevelop uifigure-Based Apps についてさらに検索

タグ

製品


リリース

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by