How can I graph an average and individual participant data?

4 views (last 30 days)
Hello,
I'm trying to create a graph that shows the amount of times a figure was rated on a scale of 0-3. I used the for loop below to examine results (apologies, but the needed variables are only in the for loop).
%find result files
filename = 'RESULTS_FILE.txt'
count_all = [];
for folder = 3:length(contents)
%cd(contents(folder).name)
T = readtable(filename)
T_target_nomask = T((strcmp(T.item, 'LowLeft.png') |...
strcmp(T.item, 'LowRight.png') |...
strcmp(T.item, 'HighRight.png') | ...
strcmp(T.item, 'HighLeft.png')),:)
T_target_nomask = T_target_nomask(strcmp(T_target_nomask.mask, 'empty.png'), :);
[count, rating] = hist(T_target_nomask.Button_press_1_, [0:3])
count_all = cat(1, count_all, count)
cd ..
T_target_mask = T((strcmp(T.item, 'LowLeft.png') |...
strcmp(T.item, 'LowRight.png') |...
strcmp(T.item, 'HighRight.png') | ...
strcmp(T.item, 'HighLeft.png')),:)
T_target_mask = T_target_mask(strcmp(T_target_mask.mask, 'mask.png'), :);
[count, rating] = hist(T_target_mask.Button_press_1_, [0:3])
count_all = cat(1, count_all, count)
cd ..
T_notarget_mask = T((strcmp(T.item, 'empty.png')),:)
T_notarget_mask = T_notarget_mask(strcmp(T_notarget_mask.mask, 'mask.png'), :);
[count, rating] = hist(T_notarget_mask.Button_press_1_, [0:3])
count_all = cat(1, count_all, count)
cd ..
T_notarget_nomask = T((strcmp(T.item, 'empty.png')),:)
T_notarget_nomask = T_notarget_nomask(strcmp(T_notarget_nomask.mask, 'empty.png'), :);
[count, rating] = hist(T_notarget_nomask.Button_press_1_, [0:3])
count_all = cat(1, count_all, count)
cd ..
end
In practice, it should run through a participant's data file, looks for the result files (marked as a .txt file), counts the rating for a given condition (namely if there's a target or not, and if there's a mask or not; these are the ones parked.png). the results are added to 3 variables: count, count_all, and rating. I put it into a graph using this format
figure;
plot(rating, count, 'o-')
hold on;
plot([0 1 2 3],[100 50 20 10], 'o-')
xlabel('rating'), ylabel('number of trials'), title('average ratings')
legend('experimental', 'projected')
However, if I use the count variable, I have a single line that doesn't make any logical sense (ie, only 50 ratings total when there should be over 200) like in figure 1. If I replace count with count_all, I end up with dozens of lines overlapping, way more than the subjects I have. How can I average these numbers into a single line, or at least the correct numbers for each subject?

Answers (1)

Dave B
Dave B on 16 Sep 2021
It's a little difficult to visualize what this looks like, but here's what i took away from looking at your code
  • you have a thing called 'count' for each iteration of your loop
  • count is the result of calling hist
  • you want to plot both the average (across iterations) of count, and each individual count.
I think you're storing your counts in one big vector, so you have a count for each bin in your histogram, but all in a big vector. You could probably use reshape to get this into the shape you want for plotting. What I mean by that is you currently have
[ participant1bin1, participant1bin2, participant1bin3, ... participant2bin1, participant2bin2, ....]
and you can reshape to
[ participant1bin1, participant1bin2, participant1bin3, ...
participant2bin1, participant2bin2, ....]
But I wouldn't take this approach, instead it makes more sense to just store the data in the correct order. In general, instead of appending to an array, just specify where you should go in the loop. Here's an example where I bin some random normal data:
bincenters = -3:3;
data=randn(5,100);
binned_data = nan(height(data), length(bincenters));
for i = 1:height(data)
binned_data(i,:) = hist(data(i,:), bincenters);
end
Now, binned_data has a row for each histogram, and a column for each bin. By default, plot will make a series for each column rather than each row, but if we specify an x, it knows what to do.
plot(bincenters, binned_data)
Now let's calculate the mean and put it on top of there:
mu = mean(binned_data);
hold on
plot(bincenters, mu, 'k-','linewidth',1.5)
To summarize: you're getting into trouble because you have a big long row vector and MATLAB doesn't know where one series ends and the next starts. You could probably use reshape to turn that vector into a matrix, but the better approach is to just store it as a matrix in the first place. Initialize the matrix before the loop and then store each row in the matrix rather than 'appending'.
Some other tips on looking at your code:
  • I recommend histcounts over hist
  • instead of using cd, it's better to specify the full path to the filenames

Categories

Find more on Line Plots in Help Center and File Exchange

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!