Calculations/Data-Analyzer/+Plotter/plotAndCompareG2Mean.m

151 lines
6.3 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function plotAndCompareG2Mean(results1, results2, varargin)
%% plotAndCompareG2Mean
% Author: Karthik
% Date: 2025-09-12
% Version: 1.0
%
% Description:
% Compare first cumulant (mean) of g²(θ) for two datasets.
% Plots mean ± standard deviation of g² values at the desired θ
%
% Inputs:
% results1, results2 : g2_analysis_results objects
%
% Notes:
% Dataset 1 = Solid line
% Dataset 2 = Dashed line
% Marker shape encodes θ value (consistent across datasets)
% Dataset colors are distinct
% --- Parse name-value pairs ---
p = inputParser;
addParameter(p, 'Title', 'Mean Comparison', @(x) ischar(x) || isstring(x));
addParameter(p, 'XLabel', 'Scan Parameter', @(x) ischar(x) || isstring(x));
addParameter(p, 'YLabel', 'Mean (\kappa_1)', @(x) ischar(x) || isstring(x));
addParameter(p, 'YLimits', [], @(x) isnumeric(x) && numel(x)==2);
addParameter(p, 'FontName', 'Arial', @ischar);
addParameter(p, 'FontSize', 14, @isnumeric);
addParameter(p, 'FigNum', [], @(x) isempty(x) || (isnumeric(x) && isscalar(x)));
addParameter(p, 'SkipSaveFigures', false, @islogical);
addParameter(p, 'SaveFileName', 'G2MeanComparison.fig', @ischar);
addParameter(p, 'SaveDirectory', pwd, @ischar);
addParameter(p, 'DesiredTheta', [pi/12 pi/6 pi/3 pi/2 2*pi/3 5*pi/6], @(x) isnumeric(x) && isvector(x));
parse(p, varargin{:});
opts = p.Results;
% --- Helper to extract mean, STD, and SEM at desired θ ---
function [xvals, yMean, yStd, ySEM, thIdx] = extractData(results)
xvals = results.scan_parameter_values(:); % [N_params × 1]
N_params = numel(xvals);
thetaVals = results.theta_values; % all θ
desiredTheta = opts.DesiredTheta;
[~, thIdx] = arrayfun(@(t) min(abs(thetaVals - t)), desiredTheta);
Ndesired = numel(desiredTheta);
yMean = zeros(N_params, Ndesired); % [scan × θ]
yStd = zeros(N_params, Ndesired);
ySEM = zeros(N_params, Ndesired);
for i = 1:N_params
G = results.g2_curves{i}; % [N_reps × N_theta] for this scan parameter
for j = 1:Ndesired
th = thIdx(j);
data = G(:, th); % all reps for this θ at this scan param
yMean(i,j) = mean(data); % mean across reps
yStd(i,j) = std(data,0,1); % std across reps
ySEM(i,j) = std(data,0,1)/sqrt(numel(data)); % SEM
end
end
end
% --- Extract data for both datasets ---
[x1, yMean1, yStd1, ySEM1, thIdx] = extractData(results1);
[x2, yMean2, yStd2, ySEM2, ~] = extractData(results2);
% --- Legend labels for θ ---
thetaLabels = arrayfun(@(t) sprintf('\\pi/%g', round(pi/t)), opts.DesiredTheta, 'UniformOutput', false);
% --- Line styles for datasets ---
lineStyles = {'-', '--'}; % solid for dataset1, dashed for dataset2
% --- Colors per θ ---
%{
cmapFull = Colormaps.coolwarm(256);
Ntheta = numel(thIdx);
startColor = cmapFull(1,:);
endColor = cmapFull(end,:);
thetaColors = [linspace(startColor(1), endColor(1), Ntheta)', ...
linspace(startColor(2), endColor(2), Ntheta)', ...
linspace(startColor(3), endColor(3), Ntheta)'];
%}
cmapFull = Colormaps.coolwarm(256);
Ntheta = numel(thIdx);
% Split into two halves: blue side (1:128), red side (129:256)
blueSide = cmapFull(1:100, :); % cut before gray
redSide = cmapFull(157:end, :); % cut after gray
% Concatenate to avoid center
cmapTrimmed = [blueSide; redSide];
% Now sample evenly from this trimmed colormap
indices = round(linspace(1, size(cmapTrimmed,1), Ntheta));
thetaColors = cmapTrimmed(indices, :);
% --- Create figure ---
if isempty(opts.FigNum), fig = figure; else, fig = figure(opts.FigNum); end
clf(fig);
set(fig,'Color','w','Position',[100 100 950 750]);
ax = axes(fig); hold(ax,'on'); grid(ax,'on');
% Set axes font for labels and numbers
set(ax, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~isempty(opts.YLimits)
ylim(ax, opts.YLimits);
end
xlabel(ax, opts.XLabel, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
ylabel(ax, opts.YLabel, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title(ax, opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize+2);
% --- Plot each θ with SEM ---
for idx = 1:Ntheta
c = thetaColors(idx,:);
% Dataset 1 -> solid line + marker + SEM
errorbar(ax, x1, yMean1(:,idx), ySEM1(:,idx), 'LineStyle', lineStyles{1}, ...
'Color', c, 'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 7, 'MarkerFaceColor', c);
% Dataset 2 -> dashed line + marker + SEM
errorbar(ax, x2, yMean2(:,idx), ySEM2(:,idx), 'LineStyle', lineStyles{2}, ...
'Color', c, 'LineWidth', 2, 'Marker', 's', 'MarkerSize', 7, 'MarkerFaceColor', c);
end
% --- Line-only legend for θ ---
thetaHandles = gobjects(Ntheta,1);
for m = 1:Ntheta
thetaHandles(m) = plot(ax, NaN, NaN, 'LineStyle','-', 'Color',thetaColors(m,:), ...
'LineWidth',6, 'Marker','none');
end
legend(ax, thetaHandles, thetaLabels, 'Location','northeast', 'FontSize', opts.FontSize-2);
% --- Dataset legend (solid/dashed + marker) ABOVE AXES ---
axLegend = axes(fig,'Position',[0.65 0.65 0.25 0.15],'Visible','off');
hold(axLegend,'on');
% Create dummy plots for legend with line style + marker in black
d1 = plot(axLegend, NaN, NaN, 'LineStyle', lineStyles{1}, ...
'Color','k', 'Marker','o', 'MarkerFaceColor','k', 'MarkerSize',7, 'LineWidth',2);
d2 = plot(axLegend, NaN, NaN, 'LineStyle', lineStyles{2}, ...
'Color','k', 'Marker','s', 'MarkerFaceColor','k', 'MarkerSize',7, 'LineWidth',2);
legend(axLegend,[d1 d2],{'D -> S','S -> D'}, ...
'FontName', opts.FontName, 'FontSize', opts.FontSize+2, ...
'Orientation','vertical', 'Box','off');
% --- Save figure ---
if ~opts.SkipSaveFigures
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
end
end