Help with GUI Layout toolbox

12 vues (au cours des 30 derniers jours)
Sankar Mahadevan
Sankar Mahadevan le 4 Mar 2018
Hello,
I am trying to add a legend to the dockexample as shown below (from the GUI layout toolbox). But when I do this, the plot gets erased and I can only see the legend notations on the axes. How do I plot and add a legend.
I believe since the parent of the axes is the panel, the legend is not a child of the axes.
Not sure how to fix this.
Please see the code below
function dockexample()
%DOCKEXAMPLE: An example of using the panelbox dock/undock functionality
% Copyright 2009-2013 The MathWorks Ltd.
% Create the window and main layout
fig = figure()
box = uix.HBox( 'Parent', fig );
uicontrol( 'Style', 'listbox', 'Parent', box, 'String', {'Item 1','Item 2'} );
% Add three panels to the box
panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
% Add some contents
uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} );
uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} );
box1 = uix.VBox( 'Parent', panel{3} );
box2 = uix.HBox( 'Parent', box1 );
uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', box1 );
uicontrol( 'Style', 'PushButton', 'String', 'Button 4', 'Parent', box2 );
uicontrol( 'Style', 'PushButton', 'String', 'Button 5', 'Parent', box2 );
% Set the dock/undock callback
set( panel{1}, 'DockFcn', {@nDock, 1} );
set( panel{2}, 'DockFcn', {@nDock, 2} );
set( panel{3}, 'DockFcn', {@nDock, 3} );
axes1 = axes( 'Parent', panel{1})
theta = 0:360;
plot(axes1,theta, sind(theta), theta, cosd(theta))
legend('sin','cos')
%-------------------------------------------------------------------------%
function nDock( eventSource, eventData, whichpanel ) %#ok<INUSL>
% Set the flag
panel{whichpanel}.Docked = ~panel{whichpanel}.Docked;
if panel{whichpanel}.Docked
% Put it back into the layout
newfig = get( panel{whichpanel}, 'Parent' );
set( panel{whichpanel}, 'Parent', box );
delete( newfig );
else
% Take it out of the layout
pos = getpixelposition( panel{whichpanel} );
newfig = figure( ...
'Name', get( panel{whichpanel}, 'Title' ), ...
'NumberTitle', 'off', ...
'MenuBar', 'none', ...
'Toolbar', 'none', ...
'CloseRequestFcn', {@nDock, whichpanel} );
figpos = get( newfig, 'Position' );
set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] );
set( panel{whichpanel}, 'Parent', newfig, ...
'Units', 'Normalized', ...
'Position', [0 0 1 1] );
end
end % nDock
%-------------------------------------------------------------------------%
function nCloseAll( ~, ~ )
% User wished to close the application, so we need to tidy up
% Delete all windows, including undocked ones. We can do this by
% getting the window for each panel in turn and deleting it.
for ii=1:numel( panel )
if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' )
figh = ancestor( panel{ii}, 'figure' );
delete( figh );
end
end
end % nCloseAll
end % Main function
  2 commentaires
Walter Roberson
Walter Roberson le 4 Mar 2018
Try
legend(axes1, {'sin','cos'})
Sankar Mahadevan
Sankar Mahadevan le 4 Mar 2018
Hi Walter, that doesn't work. I tried doing that.

Connectez-vous pour commenter.

Réponse acceptée

Mohammad Askari
Mohammad Askari le 26 Juin 2018
Modifié(e) : Mohammad Askari le 13 Avr 2022
Method 1.
As explained in the documentation, one way of doing it is to create a uicontainer parent for the axes to enable correct legend/colorbar behavior.
So simply change the axes creation line to the following:
axes1 = axes('Parent', uicontainer('Parent', panel{1}))
Method 2.
While this should work perfectly fine for most cases, you may not like the slight (not easily noticeable) shifting of the axes' position. I personally needed to come up with another solution for my own GUI due to my obsession with perfect positioning and alignment. This is not as neat as the above method, but it does the job and no longer needs to deal with the positioning of a uicontainer object which can get tricky in some cases.
You should first create a VBox or HBox container parent for your axes only. Then create the axes, add the legend, and set the Widths of the HBox or (Heights of the VBox) to [-1 0]. Finally, update your legend handle location value to your liking. I observed that resizing the figure (HBox/VBox axes container) resets the location of the legend object for some unknown reason. So I fixed this by adding a SizeChangedFcn callback to the container to fix this.
In short, you can achieve this by replacing your axes creation lines of your code with the following lines:
axesContainer = uix.HBox('Parent',panel{1},'SizeChangedFcn',{@GUIAxesLegendFix;'northeast'});
axes1 = axes('Parent', axesContainer);
theta = 0:360;
plot(axes1,theta, sind(theta), theta, cosd(theta))
LegendHandle = legend('sin','cos');
axesContainer.Widths = [-1 0];
LegendHandle.Location = 'northeast';
and add this callback function to the end of your code
function GUIAxesLegendFix(Handle,~,LegendLocation)
try Handle.Contents(2).Location = LegendLocation; catch, end
end
I just added a try, catch to the callback to prevent giving any error during resizing if you decide to add a legend to the container later manually. I also attached an updated version of your sample code with the method 2 solution. I suggest you try the more straightforward approach in the documentation and if you do not like the result, try the 2nd method.

Plus de réponses (0)

Catégories

En savoir plus sur Migrate GUIDE Apps dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by