Setting Position of uiaxes within uipanel

I want to create a GUI with variable numbers of uipanels depending on how many datasets are being examined (for instance, data from 4 instruments would display 4 uipanels.
Each panel should have a uislider and a plot displaying the data. Here's my code so far:
fig = uifigure('Name', 'Brush Detections');
fig.WindowState = 'maximized';
grd = uigridlayout(fig, [nplot, 1]);
% t{instrumentNumber} and x{instrumentNumber} are the time and amplitude data form each instrument
for iplot = 1:numInstruments
p(iplot) = uipanel(grd, 'Title', ['Receiver ', num2str(iplot)]);
% pause(2)
sld(iplot) = uislider(p(iplot), 'Position', [10, 30, 150, 3]);
ax(iplot) = uiaxes(p(iplot), 'Position', [180, 3, p(iplot).Position(3)-200, p(iplot).Position(4)-20]);
plot(ax(iplot), t{iplot}, x{iplot});
hold off
end
I'm trying to set the uiaxes to fill the remainder of the uipanel, but for some reason p(iplot).Position gives the incorrect value for the panel position. I believe this is because MATLAB hasn't finished executing all the uipanel properties before trying to execute the subsequent lines. I can get it to work properly most of the time if I put a "pause" after the p(iplot) = uipanel(grd, 'Title', ['Receiver ', num2str(iplot)]);, but the pause has to be over 2 seconds long to work consistently. Is there a way to pause only until the panel is fully generated? Or to link the uiaxes position to the uipanel position so if one updates the other does to? If the user resizes the uifigure window, it would be nice if the plot and sliders resized proportionally, too, if possible.

 Accepted Answer

Rik
Rik on 31 Dec 2021
For automatically updating positions you should set the unit property to normalized.
As for the elements not being fully initialized, you could experiment with drawnow to force a graphics update.

4 Comments

Thanks for the response. I try to set the uiaxes plot to "normalized", but I get the following error:
"Functionality not supported with figures created with the uifigure function."
Is there a workaround to allow uiaxes position units to be set to 'normalized'?
You might be able to use the SizeChangedFcn of the uifigure to change the size in response to any size changes.
If you're not working with AppDesigner it should be easy to switch back to a normal figure. There the Normalized option will be available.
It continues to amaze me how bad the performance of uifigures is compared to normal figures. There must be an important benefit I'm missing. Easy conversion to a web app? That seems a bit of a niche use case to push everybody working with GUIDE to move to AppDesigner, instead of overhauling it to a GUIDE 2.0.
Thanks! I accepted your answer because you actually gave me two working solutions.
First solution: Adding drawnow after creating the uipanel works as long as the uifigure doesn't already exists. For whatever reason, if the uifigure already exists when I try to set those positions, it calculates the positions incorrectly.
Second solution: using figure instead of uifigure. I had initially done this, but the slider callbacks weren't working and I thought it had something to do with using a figure instead of a uifigure. It turns out I just had the callbacks programmed wrong. I'm not sure what the benefit of uifigure is either.
The AppDesigner was too limiting for me since I need a variable number of panels, depending on how many sensors are being used. But both of these suggestions seems to be doing the trick now.
Glad to be of help

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2020a

Asked:

on 31 Dec 2021

Commented:

Rik
on 6 Jan 2022

Community Treasure Hunt

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

Start Hunting!