Update figure in background without stealing focus?

102 views (last 30 days)
I have a MATLAB script that periodically loads data output from a external model simulation of fluid flow, and then plots (or re-plots) it. When data are plotted, the figure window becomes the active window and is brought to the front of the screen, stealing the focus from any other window (emacs, word, etc).
I would like the matlab figure to simply update in the background so I can visually track model progress while working on other things.
Thanks!
  1 Comment
Jess
Jess on 11 Jan 2021
Oh for this to be a universal preference or setting that a MATLAB user could toggle and set and forget!

Sign in to comment.

Accepted Answer

Sean de Wolski
Sean de Wolski on 10 Apr 2012
How are you updating the figure? For example this little function with a timer that updates a plot doesn't steal focus from me.
function example_focusin
T = timer('timerfcn',@updatePlot,'period',5,'executionmode','fixedrate','taskstoexecute',10);
figure;
h = plot(rand(1,10));
start(T);
function updatePlot(src,evt)
set(h,'ydata',rand(1,10));
end
end
  11 Comments
Walter Roberson
Walter Roberson on 19 Feb 2020
vc being the output of viscircles has no information about where the detected circles are -- that information is returned by imfindcircles() . viscircles only has information about where the circles are drawn on the plot, not where they are in the image.
Anyhow:
  1. Before: Use hgtransform() to create a reference hg transform group object.
  2. Before: Use plot() or line() to create a single circle of radius 1 and center [0 0], parented to the above hgtransform group. Do not use viscircles() for this purpose: for whatever reason, you cannot parent a viscircles() to a hgtransform group.
  3. Before: initialize a pool of handle objects with hgobjects(0)
  4. In loop: do the detection of circles
  5. In loop: count how many circles you got back
  6. In loop: if the number of circles you got back is fewer than the number of elements in the pool, then set() the extra pool entries 'Visible', 'off' -- do not delete them, just set them off.
  7. In loop: if the number of circles you got back is more than the number of elemetns in the pool, then use copyobj() as many times as needed to create copies of the reference hgtransform group, adding them to the pool.
  8. In loop: For as many entries as there are circles detected this time around, set the corresponding hgtransform group to have a transform matrix that scales by the detected radius, and translates by the detected center.
  9. In loop: set the Visible property to 'on' for the first so-many entries in the pool.
  10. In loop: drawnow() to make the changes visible.

Sign in to comment.

More Answers (2)

Aastav Sen
Aastav Sen on 23 Nov 2020
This works for me (adding data to a plot within a loop without having Matlab steal the focus so I can work on other things at the same time)! So in a nutshell:
Call before your loop:
fg = figure(1)
But during your loop when you want to update the contents of a figure this requires you to 'grab' the figure and set it to your current figure handle = 'gcf'. You do this using:
set(0,'CurrentFigure',fg);
Note: that if you instead used in you loop:
fg = figure(1)
This would set the 'gcf' to our figure (what we want), but, would also steal the focus (what we don't want)!
Hope this helps.
  1 Comment
Jess
Jess on 11 Jan 2021
That looks like something that would work if one was updating a single figure many times. (Is that correct?) If one was to make a dozen plots once each, wouldn't one have to do that a dozen times?

Sign in to comment.


Sergio López-Ureña
Sergio López-Ureña on 19 Oct 2020
You can select the figure by number.
set(groot,'CurrentFigure',figNumber);
It does exactly the same that
figure(figNumber);
but without focusing.
It is useful when you don't want to save the figure handler.
  1 Comment
Matthieu
Matthieu on 15 Aug 2023
Edited: Matthieu on 15 Aug 2023
Thanks Segio for this tip, I then integrated it into a wrapper function to replace the figure() function:
function fig(indFig)
% Convenient function to replace the figure(X),
% Very convenient in loop where an update of figure must be done without stealing the focus
if nargin == 0
figure() % if no argument then just creates a new figure, but steal focus
return
end
try
set(groot,'CurrentFigure',indFig); % replace figure(indFig) without stealing the focus
catch
figure(indFig) % if indFig is not an exsting figure it creates it (and steal the focus)
end
% Drawnow is here in order to force update of the figure,
% Otherwise I observed that content of figure is not updated in loop.
% Normally 'drawnow' should take place at the end of plotting
% and NOT before plotting however in loop functions it updates
% with one loop late, this prevent to write 'drawnow' everywhere in the code.
drawnow

Sign in to comment.

Categories

Find more on Graphics Performance in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!