Plot to figures without bringing them into foreground

╄→尐↘猪︶ㄣ 提交于 2020-01-04 02:11:06

问题


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?


回答1:


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.




回答2:


The relevant part can be found in the part of the documentation of scatter that includes the input ax:

scatter(ax,___) plots into the axes specified by ax instead of into the current axes.

This allows the user to specify an axis handle pointing to which axes should be used for drawing the scatter plot. Thus if you skip using figure in your code and use the ax input instead, you avoid the "bring to front" behavior associated with figure.

You can modify your code as follows:

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


来源:https://stackoverflow.com/questions/48033731/plot-to-figures-without-bringing-them-into-foreground

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!