Plot with shaded standard deviation

8 views (last 30 days)
MARCO
MARCO on 11 Mar 2024
Commented: Voss on 11 Mar 2024
I am having issue with both patch and fill function. I am not able to fill the space between 'y_values_upper' and 'y_values_lower' curves. Thanks in advance for the help.
Here it is my code:
% Import the data
% Prompt the user to choose a file
[filename, filepath] = uigetfile('*.txt', 'Select a text file');
file_name = filename;
remove = '.txt';
file_name_clean = strrep(file_name, remove, '');
%%
%ZP AVERAGE
plot_name = ['Average_' file_name_clean '.svg'];
% Import data from text file
opts = delimitedTextImportOptions("NumVariables", 6);
opts.DataLines = [2, 84];
opts.Delimiter = "\t";
opts.VariableNames = ["Count", "ZP1", "Count2", "ZP2", "Count3", "ZP3"];
opts.SelectedVariableNames = ["Count", "ZP1", "ZP2", "ZP3"];
opts.VariableTypes = ["double", "double", "string", "double", "string", "double"];
opts.ExtraColumnsRule = "ignore";
opts.EmptyLineRule = "read";
% Construct the full file path
file_path = fullfile(filepath, file_name);
ZpData = readtable(file_path, opts);
% Calculate averages and standard deviations
average_Zp = mean([ZpData.ZP1, ZpData.ZP2, ZpData.ZP3], 2, 'omitnan');
std_dev_Zp = std([ZpData.ZP1, ZpData.ZP2, ZpData.ZP3], 0, 2, 'omitnan');
% Plotting the data with logarithmic x-axis and error bars for averages and standard deviations
figure;
plot(ZpData.Count, average_Zp, '-', 'LineWidth', 2, 'DisplayName', 'Zeta Potential');
hold on;
% Define vectors for the patch
y_values_upper = average_Zp + std_dev_Zp;
y_values_lower = average_Zp - std_dev_Zp;
% Create shaded area for the upper standard deviation
plot(ZpData.Count, y_values_lower, 'Color', 'r', 'DisplayName', 'SD');
plot(ZpData.Count, y_values_upper, 'Color', 'r', 'HandleVisibility', 'off');
title('Zeta Potential');
xlabel('ZP (mV)');
ylabel('Total count');
grid on;
legend;
hold off;
% Set x-axis limit starting from 0
xlim([-100, 100]);
% Set x-axis ticks every 10 values
xticks(-100:10:100);
% Set the minor ticks
ax = gca;
ax.XAxis.MinorTick = 'on';
ax.XAxis.MinorTickValues = -100:5:100;
% Find peaks in the average_Zp data
[peaks, peak_indices] = findpeaks(average_Zp);
% Find the maximum peak
[max_peak, max_index] = max(peaks);
% Get the corresponding x-value for the maximum peak
x_value_at_max_peak = ZpData.Count(peak_indices(max_index));
% Display the peak information
fprintf('Maximum Peak Value: %.2f\n', max_peak);
fprintf('Corresponding X-Value: %.2f\n', x_value_at_max_peak);
% Add text annotation for the maximum peak
text(x_value_at_max_peak, max_peak, sprintf('Max Peak at %.2f', x_value_at_max_peak), ...
'HorizontalAlignment', 'left', 'VerticalAlignment', 'bottom');
% Create a new folder
folderName = 'zp_graph';
mkdir(folderName);
% Save the plot as an image file (e.g., PNG)
saveas(gcf, fullfile(folderName, plot_name));

Accepted Answer

Voss
Voss on 11 Mar 2024
It looks like your y_values_upper and y_values_lower are column vectors, so be sure to take that into account when creating the data for the patch. Something like this works:
% column vectors:
y_values_upper = 2*rand(25,1);
y_values_lower = -2*rand(25,1);
x = (1:25).';
% make the patch
figure
patch([x; flipud(x)],[y_values_upper; flipud(y_values_lower)],'g')
If they were row vectors, the syntax would be different:
% row vectors:
y_values_upper = 2*rand(1,25);
y_values_lower = -2*rand(1,25);
x = 1:25;
% make the patch
figure
patch([x fliplr(x)],[y_values_upper fliplr(y_values_lower)],'g')
  2 Comments
MARCO
MARCO on 11 Mar 2024
Edited: MARCO on 11 Mar 2024
thanks a lot! with the first syntax it works!
I also implemented the opacity and removed the edge in this way:
patch([ZpData.Count; flipud(ZpData.Count)],[y_values_upper; flipud(y_values_lower)],'r', 'FaceAlpha', 0.15, 'EdgeColor', 'none', 'DisplayName', 'SD')
Voss
Voss on 11 Mar 2024
You're welcome! Looks good.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!