Как построить «движущийся» график для значений в реальном времени вдоль оси X (используя psychtoolbox)? - PullRequest
0 голосов
/ 20 декабря 2018

Я пишу код для эксперимента в реальном времени с использованием psychtoolbox для представления стимула.В моем эксперименте мне нужно показать предмету график, который показывает его эффективность.Я построил график с помощью этого простого кода:

        % Draw the graph
        figure('visible','off','color',[0 0 0]);
        pcolor([0 Num_timepoint+2],[-10 0],ones(2,2));
        hold on;
        pcolor([0 Num_timepoint+2],[0 10],2*ones(2,2));
        colormap([79 167 255;255 187 221]/256);      
        plot(1:subloop,value0,'*-',...
        'color',[0,0,0],...
        'LineWidth',1,...
        'MarkerSize',5,...
        'MarkerEdgeColor','k',...
        'MarkerFaceColor',[0.5,0.5,0.5]);
        axis([0,Num_timepoint+2,-10,10]);
        saveas(gcf,'line_chart.png');   %save it
        close(figure);
        line_chart=imread('line_chart.png');   %read it
        resized_plot=imresize(line_chart,0.5);
        imageSize = size(resized_plot);
        [imageHeight,imageWidth,colorChannels]=size(resized_plot);
        bottomRect = [xCenter-imageWidth/1.5, yCenter+gapdown, xCenter+imageWidth/1.5, yCenter+gapdown+imageHeight];
        imageDisplay=Screen('MakeTexture', win0, resized_plot);
        Screen('DrawTexture', win0, imageDisplay, [], bottomRect);

К сожалению, этот простой код очень медленный.Кроме того, я не смог заставить график двигаться вдоль оси x, как только появилось новое значение.

Любая помощь будет потрясающей.Заранее благодарим за ваши усилия.

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Если вы хотите переместить данные на одну выборку, вы можете использовать функцию circshift.Например, если вы хотите, чтобы новые значения отображались слева, вы можете сместить все значения на 1 образец вправо, а затем добавить новое значение в первую позицию.

Для преобразования фигуры MATLAB в Psychtoolboxтекстуры, вам не нужно сохранять, а затем загружать временные изображения.Вместо этого вы можете использовать функцию getframe для захвата данных фигур MATLAB, которые затем можно передать MakeTexture, чтобы превратить их в текстуру Psychtoolbox.

Я не уверен, какие значения вы на самом деле используете дляsubloop, value0 и т. д., но есть пример, который, я думаю, может быть близок к тому, что вы хотите.В этом примере показано 30 кадров рисунков, причем каждый рисунок отображается на экране в течение 1 секунды.Новые точки данных генерируются случайным образом и появляются в левой части рисунка.

В зависимости от деталей вашего эксперимента, вы можете обнаружить, что этот подход все еще слишком медленный.Вы также можете создать фигуру напрямую с помощью таких методов рисования в Psychtoolbox, как DrawLines и т. Д., Хотя это потребует дополнительных усилий.

try

    win0 = Screen('OpenWindow', 0, 0);

    Num_timepoint = 100;
    subloop = 100;
    value0 = zeros(1,100);

    num_demo_frames = 30;

    % Draw the graph
    fig_h = figure('visible','off','color',[0 0 0]);
    pcolor([0 Num_timepoint+2],[-10 0],ones(2,2));
    hold on;
    pcolor([0 Num_timepoint+2],[0 10],2*ones(2,2));
    colormap([79 167 255;255 187 221]/256);
    plot_h = plot(1:subloop,value0,'*-',...
        'color',[0,0,0],...
        'LineWidth',1,...
        'MarkerSize',5,...
        'MarkerEdgeColor','k',...
        'MarkerFaceColor',[0.5,0.5,0.5]);
    axis([0,Num_timepoint+2,-10,10]);

    for f = 1:num_demo_frames
        new_value = randn(1,1);
        data_values = plot_h.YData;
        data_values = circshift(data_values, 1);
        data_values(1) = new_value;
        plot_h.YData = data_values;

        plot_values = getframe(fig_h);
        imageDisplay=Screen('MakeTexture', win0, plot_values.cdata);
        Screen('DrawTexture', win0, imageDisplay);
        Screen('Flip', win0);
        WaitSecs(1);
    end

    sca;

catch e
    sca;
    rethrow(e);
end
0 голосов
/ 20 декабря 2018

Почему вы сохраняете фигуру и перерисовываете изображение?Может быть, я чего-то упускаю, но вы должны быть в состоянии выполнить то, что вам нужно, обновив существующий график свежими данными, используя свойства ручки графика:

 .... First time through we need the initial plot ....
 % Set up figure with colormaps and such but leave as 'visible','on'
 hPlot = plot(plot(1:subloop,value0,'*-',...
    'color',[0,0,0],...
    'LineWidth',1,...
    'MarkerSize',5,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5]);
 hAxes = gca;


 .... Loop over your real time updates ....
 % Assuming value0 has subject's results from t=0 to t=now 
 hPlot.XData = value0; hPlot.YData = [1:subloop];   
 hAxes.XLim = [0 numTimePoints+2];
 hAxes.YLim = [-10 10]

 .... Continue test and update value0 ....

Я думаю, это должно поддерживать ваши графики в актуальном состоянии.без необходимости сохранять рисунок как изображение в файл, а затем снова открыть изображение для отображения на объекте.

...