Bratode
Bratode

Reputation: 1

Update Specific Object in Matlab GUI

I am currently developing a GUI for MATLAB which is updated using a (relatively) high frequency. It contains 3 Axes and a bunch of check boxes etc. In every iteration, I use the drawnow command to update everything - which works nice and dandy.

Little more background: the GUI is completely controlled via script. I use handlers to get the info I need.

The problem: I am running into performance issues. I am now looking for a way to update ONLY the checkbox status but leave everything else untouched. Currently I am not able to read back a changed checkbox status without using drawnow - and I am not able to find anything about updating specific objects.

Upvotes: 0

Views: 300

Answers (2)

Suever
Suever

Reputation: 65460

Unfortunately, there is no way to flush the event/callback queue without rendering the graphics, only the other way around. There is also no way to flush the event/callback queue for a specific graphics object which is required for the Value property of the uicontrol to be updated.

What you can do though, is rather than using the vanilla drawnow, consider using the limitrate input to drawnow which ensures that if you are updating your plots at a very high frequency, they are only actually rendered at a maximum of 20 frames per second. This will prevent you from having a significant lag due to all of the render events.

drawnow limitrate

From the documentation:

drawnow limitrate limits the number of updates to 20 frames per second. If it has been fewer than 50 milliseconds since the last update, or if the graphics renderer is busy with the previous change, then drawnow discards the new updates. Use this command if you are updating graphics objects in a loop and do not need to see every update on the screen. Skipping updates can create faster animations. Pending callbacks are processed, so you can interact with figures during animations.

And as an example:

hcheck = uicontrol('style', 'check', 'String', 'Green');
hplot = plot(rand(10,1));
set(gca, 'ylim', [0 1], 'xlim', [1 10])

originalColor = get(hplot, 'Color');

while true
    set(hplot, 'YData', rand(10,1))

    if get(hcheck, 'value')
        set(hplot, 'Color', 'g')
    else
        set(hplot, 'Color', originalColor)
    end

    drawnow limitrate
end

enter image description here

Running that example on my Mac, without using the limitrate option, I was able to loop through the while loop about 42 times per second. With the limitrate option enabled, I was able to loop through 767 times per second.

Upvotes: 2

nirvana-msu
nirvana-msu

Reputation: 4077

You might be better off using pure swing components, such as JCheckBox. They do not have such issues as uicontrols do. Try running the below example and you'll see that you can query new checkbox state right after it changes, without having to use drawnow:

figure();
jCB = javaObjectEDT(javax.swing.JCheckBox('Green',0));
javacomponent(jCB, [20, 20, 60, 20], gcf);
pause(0.1);

while true
    plot(1);   % just some random code
    display(jCB.isSelected());
end

So you don't necessarily need to flush the even queue to query the updated graphics state.

Upvotes: 1

Related Questions