Home > OS >  Figure behavior varies when calling custom plot on single line or multiple lines
Figure behavior varies when calling custom plot on single line or multiple lines

Time:09-09

function plot2(x)
    hold on
    fig = gcf();
    ax = gca();

    plot(ax, x)

    fig.Visible = true;
    figure('Visible', 'off')
    hold off
end

Why does

>> plot2([1 2]); plot2([2 1])

create two figures, but

>> plot2([1 2])
>> plot2([2 1])

one? We have

  • plot2() <=> use 1 existing figure, create 1 new figure
  • >> plot2(); plot2() <=> use figure X, create figure Y, use figure Y, create figure Z.
  • >> plot2() >>plot2() <=> use figure X, create figure Y. use figure Y? create figure Z?

disp(gcf) before hold off show that new figs are being created in both cases, as in Figure (25), Figure (26).

CodePudding user response:

Note that calling plot2([1 2]); drawnow(); plot2([2 1]) on a single line uses one figure the same as two separate plot2 calls. So at a high level it's likely due to the graphics buffer not being flushed when calling both on a single line without drawnow.

However, debugging we can see this is caused by the slightly odd order of operations called by your plot2 function, which has ambiguous handling of figures by relying on gcf and using calls to hold out-of-order and without specifying the hold target axes.

In the below lines, where I've written a code line it as an extract from plot2 during a given command call:

>> plot2([1 2]); plot2([2 1])

% Calling through "plot2([1 2])"
hold on      % creates a figure and axes if one doesn't exist, or hold current
fig = gcf(); % gets the figure referenced by "hold"
ax = gca;    % gets the axes referenced by "hold"
plot(ax,x)   % plots on these axes

fig.Visible = true; % make the current figure visible
figure('Visible','off') % Create NEW figure, hidden. At this point you have 2 figures
hold off     % does NOTHING, sets hold to "off" for new (invisible) 
             %  figure which is the default anyway


% Calling through "plot2([2 1])"
hold on      % holds "on" the CURRENT figure. This will depend whether the graphics buffer 
             %  has been flushed. If not then the current figure is the hidden one created 
             %  in the previous call, if it has then the current figure is the most recent 
             %  visible figure. This is *not* specifically noted in the docs.
fig = gcf(); % gets the same figure referenced by "hold"
ax = gca;    % gets the same axes referenced by "hold"
plot(ax,x)   % plots on these axes

fig.Visible = true; % make the same "current" figure as above visible. When running with a 
                    %  graphics flush in between, this figure will already be visible 
                    %  due to the above behaviour
figure('Visible','off') % Create ANOTHER NEW figure, hidden. 
                        %  At this point you will have 3 figures!
hold off     % does NOTHING, sets hold to "off" for new (invisible) 
             %  figure which is the default anyway

You can verify my last comment about ending up with 3 figures using allFig = findall(0,'type','figure'); which will show all current figure objects including those which are hidden.

  • Related