0

I am writing a code for a real time experiment using psychtoolbox to present the stimulus. In my experiment, I need to show the subject a graph that indicates his performance. I have plotted the graph using this simple code:

        % 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);

Unfortunately, this simple code is very slow. In addition, I couldn't make the graph moving along x axis, as soon as the new value comes.

Any help would be Awesome. Thanks in advance for your efforts.

Abdul
  • 3
  • 2

2 Answers2

1

Why are you saving the figure and redisplaying as an image? Maybe I'm missing something but you should be able to accomplish what you need by updating the existing plot with the fresh data using the handles properties of the plot:

 .... 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 ....

I think that should keep your plots current without having to save the figure as image to file then reopen the image to display to subject.

Morc
  • 381
  • 2
  • 9
  • Thanks a lot for your help. It worked for the moving issue. I still can't make it plotting using the "screen" function of psychtoolbox. Actually, I need to present the graph using this toolbox. That's why I previously have to save the figure and read it. By the way, I can't combine plotting and psychtoolbox together to obtain it. – Abdul Dec 24 '18 at 14:13
0

If you want to move your data one sample, you can use the circshift function. For example, if you want your new values to appear on the left hand side, you can shift all values 1 sample rightward, then add your new value in the first position.

For converting a MATLAB figure to a Psychtoolbox texture, you don't need to save, then load the temporary images. You can instead use the getframe function to capture the MATLAB figure data, which can then be given to MakeTexture to turn it into a Psychtoolbox texture.

I'm not sure what values you're actually using for subloop, value0, etc. but there is an example that I think might be close to what you want. In this example, 30 frames of figures are plotted, with each figure being on screen for 1 second. New data points are generated randomly and appear from the left hand side of the figure.

Depending on the details of your experiment, you may find that this approach is still too slow. You could also create the figure directly via Psychtoolbox drawing methods like DrawLines, etc. though that would require more effort.

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
DMR
  • 1,479
  • 1
  • 8
  • 11