Search code examples
matlabmatlab-figure

Plot to figures without bringing them into foreground


figure;
ax1 = axes;
figure;
ax2 = axes;
x = 0; y = 0;
while ishandle(ax1) && ishandle(ax2)
    x = x + 1;
    y = y + 1;
      figure(1)
      scatter(x,y, 'MarkerEdgeColor', 'red')
      hold on
      figure(2)
      scatter(x,y, 'MarkerEdgeColor', 'blue')
      hold on
  end

In my script I have multiple figures, which are going to be updated in a loop. The figures have to be displayed, while the script is running. Unfortunately the currently updated figure is always popping in the foreground, which makes it impossible to monitor a certain figure. I understand that the calling of figure(1) and figure(2) causes this behaviour, but I how can I plot to these figures, without bringing the window into foreground?


Solution

  • As mikkola suggested in a comment, you can specify to which axes scatter or plot add data points. However, there is a better method: create a single line object, and update its xdata and ydata properties. This is both faster and more memory efficient. Your code would become:

    x = 0; y = 0;
    figure;
    h1 = plot(x,y,'ro');
    figure;
    h2 = plot(x,y,'bo');
    while ishandle(h1) && ishandle(h2)
       x = x + 1;
       y = y + 1;
       h1.XData(end+1) = x;
       h1.YData(end+1) = y;
       h2.XData(end+1) = x;
       h2.YData(end+1) = y;
       drawnow
       pause(0.1)
    end
    

    I keep a set of rules of thumb for when working with MATLAB handle graphics. These are relevant to this question:

    • Use figure only to create a new figure, or to bring an existing figure to the front (which you want to avoid in general, but sometimes is necessary).

    • Always specify with which figure or axes you want to work, by keeping and using their handles. I never rely on gcf or gca (not explicitly nor implicitly). Using the current figure is useful when typing on the command line, but in a script or a function there is the real danger than someone clicks randomly on windows while the function is executing. Creating a window then writing to gcf could end up writing to a different figure (really, I click on random things all the time).

    • Don't create more objects than necessary. Creating a new line object for every point you plot is wasteful.

    Note also that plot(...'o') is equivalent to scatter(...) unless you specify a different color or size for each point. But using the dot size or color to specify additional information is not a good way to convey that information. Read Tufte's "The visual display of quantitative information" if you're interested in learning about effective communication through graphs.