1

I'm expanding on the question asked at Expand (maximise) subplot figure temporarily — then collapse it back - I tried to post this as a comment to the original post, but I don't have sufficient privileges.

I was using the version in the comments:

function gcaExpandable

set(gca, 'ButtonDownFcn', [...
    'set(copyobj(gca, uipanel(''Position'', [0 0 1 1])), ' ...
    '    ''Units'', ''normal'', ''OuterPosition'', [0 0 1 1], ' ...
    '    ''ButtonDownFcn'', ''delete(get(gca, ''''Parent''''))''); ']);

end

which worked perfectly in Matlab 2013b. However, I'm now on 2015b and when I try to use that same buttondown function I get the following:

Error using gcaExpandable
Too many input arguments.

Error while evaluating Axes ButtonDownFcn

I don't currently understand what exactly is throwing the error. I've tried to fix it by adding the 'legacy' flag to copyobj based on the documentation:

copyobj(___,'legacy') copies object callback properties and object
application data. This behavior is consistent with versions of copyobj 
before MATLAB® release R2014b.

but that doesn't change the behavior at all. If anyone can figure out what's causing the error or how to adapt this very useful function to 2015b it would be greatly helpful! Thanks.

Chris
  • 13
  • 3
  • Posting a new question is the right thing to do. – Cris Luengo Jan 08 '18 at 19:35
  • How do you call `gcaExpandable`? Are you setting it as the `ButtonDownFcn` for an axes object? I think the intention is that you call it directly from the command line, after plotting. It sets the `ButtonDownFcn` for the axes. So you call this function, then you can click on the axes. – Cris Luengo Jan 08 '18 at 19:37
  • I call it like this - this was working in 2013b. It is added as the ButtonDownFcn for the axes after they are created. f = subplot(xx); set(f, 'ButtonDownFcn', @gcaExpandable); – Chris Jan 08 '18 at 19:49
  • Does the error appear when you first call `gcaExpandable` or when you click on the axes object? – Cris Luengo Jan 08 '18 at 19:53
  • Good question - when I click the axes. I should have included in the original post! – Chris Jan 08 '18 at 20:27
  • I don't have MATLAB at hand right now to try this out, but you could try translating to the currently preferred format (a string as callback is rather old-fashioned now). It would be something like `set(gca,'ButtonDownFcn',@(ax,~)set(copyobj(ax, uipanel(''Position'', [0 0 1 1])),''Units'', ''normal'', ''OuterPosition'', [0 0 1 1], ''ButtonDownFcn'', @(ax,~)delete(ax)));` (note that's all a single line). – Cris Luengo Jan 08 '18 at 20:45
  • In the above, each doubled quote should be single (`''`->`'`). – Cris Luengo Jan 08 '18 at 20:51
  • Thanks for that suggestion. I implemented it (with single quotes) and I am still getting the same "too many input arguments" error when I click the axes. – Chris Jan 09 '18 at 19:55
  • If you copy-paste the contents of the callback function, after `@(ax,~)`, to the command line (define `ax=gca` first), what error message do you get? It is possible that you have redefined one of the functions involved? – Cris Luengo Jan 09 '18 at 20:04

1 Answers1

0

This one works for me on MATLAB R2017a:

set(gca, 'ButtonDownFcn',@(ax,~)set(copyobj(ax,uipanel('Position',[0,0,1,1])),...
  'Units','normal', 'OuterPosition',[0,0,1,1],
  'ButtonDownFcn',@(co,~)delete(get(co,'parent'))));

You can put this inside a gcaExpandable function as in the OP.

The big difference with the code in the OP is the use of anonymous functions. Callbacks have two input arguments, the first one is the callback object (the thing clicked on), the second one can be ignored, but must be present in the function definition (hence the ~, which signals an ignored parameter).

By using anonymous functions instead of a string to be evaluated, the syntax is clearer (no doubled-up quotes).

Under Octave, the copyobj function works differently. To get the same code to work, you need more than one statement in the callback. For this it is necessary to define the callback function as a regular, named function, and pass its handle as the callback:

function gcaExpandable
    set(gca,'ButtonDownFcn',@callback);

function callback(ax,~)
panel = uipanel('Position',[0,0,1,1]);
newax = copyobj(ax,panel);
set(newax,'Units','normal', 'OuterPosition',[0,0,1,1], ...
          'ButtonDownFcn',@(~,~)delete(panel))

(The two functions above are defined in the same file gcaExpandable.m.)

Note that the code is also much cleaner this way, there is no advantage to defining it all as a one-liner. This version also works in MATLAB.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Cris- thanks for the reply. It appears that the key is the function prototype. Previously I had function gcaExpandable but with your answer I tried function gcaExpandable(~,~) and both of your suggestions worked fine. Thank you!! – Chris Jan 17 '18 at 15:43
  • I tried to vote your answer up but I don't have enough reputation.. sorry! – Chris Jan 19 '18 at 13:37