How to make a function non-blocking? Dynamic plotting in Matlab GUI

女生的网名这么多〃 提交于 2019-12-12 03:36:27

问题


It's been some time since using Matlab and I've never used it for any GUI creation until now. My goal is to have a button which I can press, and then have the results plotted as they are calculated. The button should toggle between 'Start' and 'Stop' depending on what is happening. These results are collected for several iterations and each iteration gives another data point.

My solution was to pass the axes to the function doing the calculations, which can then plot to the axes. This works, however while this is happening the button won't toggle to 'Stop' until after the plotting is complete. Can I make the function non-blocking? Am I even going about this is in the best method possible? How will I be able to stop the calculations with the 'Stop' button? Will I just need to create a thread for this (does matlab support threading)?

I have been testing my ideas with a simple function to draw a sine

function [ t,y ] = slowSin(ax)
%Plot a sin curve slowly
t = [0:0.06:4*pi];
y = sin(1.5*t);

for i = 1:length(t)
    plot(ax, t(1:i), y(1:i))
    pause(0.1)

end

I haven't thought of threading until now. I will look into that shortly, but all help is appreciated.


回答1:


First of all, MATLAB does not do multithreading for any graphics so you have to get creative.

Also, you'll want to use drawnow to flush the callback and rendering events if you're trying to do some plotting in the middle of your computations.

As far as knowing when to stop, you can maybe pass the graphics handle of the button to your computations, and it can check the value each iteration?

I have an example that uses a persistent variable to keep track of the current iteration and allows the user to "pause" the calculation by unclicking the toggle button.

function guiThing()

    figure();
    hbutton = uicontrol('style', 'toggle', 'String', 'Start');

    hplot = plot(NaN, NaN);

    nIterations = 1000;
    set(gca, 'xlim', [1 nIterations], 'ylim', [1 nIterations])

    set(hbutton, 'callback', @(s,e)buttonCallback())

    function buttonCallback()
        % If the button is depressed, calculate the thing
        if get(hbutton, 'value')
            calculateThing(hbutton, hplot, nIterations);
        end
    end
end

% This function can live anywhere on the path!
function calculateThing(hbutton, hplot, nIterations)

    % Keep track of data with persistent variables
    persistent iteration

    % First time to call this function, start at 1
    if isempty(iteration); iteration = 1; end

    for k = iteration:nIterations
        iteration = k;

        % If the button is not depressed then stop this
        if ~get(hbutton, 'value')
            return
        end

        % Update plotting in some way
        curdata = get(hplot);
        set(hplot, 'XData', [curdata.XData k], ...
                   'YData', [curdata.YData, k])

        % Flush drawing queue
        drawnow

        fprintf('Iteration: %d\n', iteration);
    end
end

You can use the persistent variables to keep track of any other data that needs to persist between iterations (and stops and starts).



来源:https://stackoverflow.com/questions/35803853/how-to-make-a-function-non-blocking-dynamic-plotting-in-matlab-gui

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