New plotting routines
This commit is contained in:
parent
ffa50e2525
commit
5fd39e31f4
@ -43,26 +43,29 @@ function plotAndCompareG2Cumulants(results1, results2, varargin)
|
||||
% --- Legend labels for θ ---
|
||||
thetaLabels = arrayfun(@(t) sprintf('\\pi/%g', round(pi/t)), opts.DesiredTheta, 'UniformOutput', false);
|
||||
|
||||
% --- Marker per θ ---
|
||||
markerList = {'o','s','^','d','v','>','<','p','h'}; % more markers if needed
|
||||
Ntheta = numel(thIdx);
|
||||
markers = markerList(mod(0:Ntheta-1, numel(markerList))+1); % cycle if Ntheta > markerList
|
||||
|
||||
% --- Line styles for datasets ---
|
||||
lineStyles = {'-', '--'}; % solid for dataset1, dashed for dataset2
|
||||
|
||||
% --- Colors per θ (generalized, using only ends of coolwarm) ---
|
||||
% --- Colors per θ ---
|
||||
%{
|
||||
cmapFull = Colormaps.coolwarm(256);
|
||||
Ntheta = numel(thIdx);
|
||||
|
||||
% pick start and end colors
|
||||
startColor = cmapFull(1, :); % deep blue
|
||||
endColor = cmapFull(end, :); % deep red
|
||||
|
||||
% interpolate RGB linearly between start and end for Ntheta points
|
||||
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 ---
|
||||
@ -85,7 +88,7 @@ function plotAndCompareG2Cumulants(results1, results2, varargin)
|
||||
% Dataset 1 -> solid line + marker
|
||||
plot(ax, x1, squeeze(kappa1(th,:,k)), ...
|
||||
'LineStyle', lineStyles{1}, 'Color', c, ...
|
||||
'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 7, ...
|
||||
'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 7, ... % markerList = {'o','s','^','d','v','>','<','p','h'}; % more markers if needed
|
||||
'MarkerFaceColor', c);
|
||||
|
||||
% Dataset 2 -> dashed line + marker
|
||||
|
135
Data-Analyzer/+Plotter/plotAndCompareG2Mean.m
Normal file
135
Data-Analyzer/+Plotter/plotAndCompareG2Mean.m
Normal file
@ -0,0 +1,135 @@
|
||||
function plotAndCompareG2Mean(results1, results2, varargin)
|
||||
%% plotAndCompareG2Mean: Compare first cumulant (mean) of g²(θ) for two datasets
|
||||
% results1, results2 : g2_analysis_results objects
|
||||
%
|
||||
% Dataset 1 = Solid line
|
||||
% Dataset 2 = Dashed line
|
||||
% Marker shape encodes θ value (consistent across datasets)
|
||||
% Dataset colors are distinct
|
||||
%
|
||||
% Plots mean ± standard deviation of g² values at the desired θ
|
||||
|
||||
% --- 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, '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');
|
||||
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');
|
||||
|
||||
d1 = plot(axLegend, NaN, NaN, 'LineStyle',lineStyles{1}, ...
|
||||
'Color','k', 'Marker','none', 'LineWidth',2);
|
||||
d2 = plot(axLegend, NaN, NaN, 'LineStyle',lineStyles{2}, ...
|
||||
'Color','k', 'Marker','none', '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
|
121
Data-Analyzer/+Plotter/plotG2CurvesMultiParam.m
Normal file
121
Data-Analyzer/+Plotter/plotG2CurvesMultiParam.m
Normal file
@ -0,0 +1,121 @@
|
||||
function plotG2CurvesMultiParam(results, scan_parameter_values, scan_reference_values, param1ValuesToPlot, param2ValuesToPlot, varargin)
|
||||
%% plotG2CurvesMultiParam: Plot g²(θ) curves for selected param1 and param2 values in a phase diagram
|
||||
%
|
||||
% Usage:
|
||||
% plotG2CurvesMultiParam(results, scan_parameter_values, scan_reference_values, ...
|
||||
% param1ValuesToPlot, param2ValuesToPlot, ...
|
||||
% 'Title','g² Curves','FontName','Arial','FontSize',14,'FigNum',1, ...
|
||||
% 'Param1Name','BField','Param2Name','Alpha', ...
|
||||
% 'HighlightEvery',10,'SkipSaveFigures',false, ...
|
||||
% 'SaveFileName','G2CurvesPhaseDiagram.fig','SaveDirectory','results');
|
||||
|
||||
% --- Parse name-value pairs ---
|
||||
p = inputParser;
|
||||
addParameter(p, 'Title', 'g² Curves', @(x) ischar(x) || isstring(x));
|
||||
addParameter(p, 'FontName', 'Arial', @ischar);
|
||||
addParameter(p, 'FontSize', 14, @isnumeric);
|
||||
addParameter(p, 'FigNum', [], @(x) isempty(x) || (isnumeric(x) && isscalar(x)));
|
||||
addParameter(p, 'Param1Name', 'Param1', @(x) ischar(x) || isstring(x));
|
||||
addParameter(p, 'Param2Name', 'Param2', @(x) ischar(x) || isstring(x));
|
||||
addParameter(p, 'HighlightEvery', 10, @(x) isnumeric(x) && isscalar(x) && x>=1);
|
||||
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
||||
addParameter(p, 'SaveFileName', 'G2CurvesPhaseDiagram.fig', @ischar);
|
||||
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
||||
parse(p, varargin{:});
|
||||
opts = p.Results;
|
||||
|
||||
% --- Convert reference/parameter values to numeric arrays ---
|
||||
scanRefArray = cell2mat(scan_reference_values(:)); % nParams × 2
|
||||
scanParamArray = cell2mat(scan_parameter_values(:)); % nTotal × 2
|
||||
|
||||
% --- Select subset based on param1ValuesToPlot and param2ValuesToPlot ---
|
||||
keepIdx = ismembertol(scanRefArray(:,1), param1ValuesToPlot, 1e-6) & ...
|
||||
ismembertol(scanRefArray(:,2), param2ValuesToPlot, 1e-6);
|
||||
scan_reference_values_plot = scan_reference_values(keepIdx);
|
||||
nParamsPlot = numel(scan_reference_values_plot);
|
||||
|
||||
% --- Warn about missing values ---
|
||||
existingP1 = param1ValuesToPlot(ismembertol(param1ValuesToPlot, unique(scanRefArray(:,1)), 1e-6));
|
||||
missingP1 = setdiff(param1ValuesToPlot, existingP1);
|
||||
existingP2 = param2ValuesToPlot(ismembertol(param2ValuesToPlot, unique(scanRefArray(:,2)), 1e-6));
|
||||
missingP2 = setdiff(param2ValuesToPlot, existingP2);
|
||||
if ~isempty(missingP1)
|
||||
warning('The following %s values were not found: %s', opts.Param1Name, num2str(missingP1));
|
||||
end
|
||||
if ~isempty(missingP2)
|
||||
warning('The following %s values were not found: %s', opts.Param2Name, num2str(missingP2));
|
||||
end
|
||||
|
||||
param1Plot = sort(existingP1, 'descend');
|
||||
param2Plot = sort(existingP2);
|
||||
|
||||
% --- Extract theta values ---
|
||||
theta = results.theta_values / pi;
|
||||
Nhighlight = opts.HighlightEvery;
|
||||
|
||||
% --- Create figure ---
|
||||
if isempty(opts.FigNum)
|
||||
fig = figure;
|
||||
else
|
||||
fig = figure(opts.FigNum);
|
||||
end
|
||||
clf(fig);
|
||||
set(fig,'Color','w','Position',[100 100 1200 800]);
|
||||
t = tiledlayout(numel(param1Plot), numel(param2Plot), 'TileSpacing','compact','Padding','compact');
|
||||
title(t, opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize+2);
|
||||
|
||||
% --- Loop over selected param1/param2 values ---
|
||||
for r = 1:numel(param1Plot)
|
||||
P1 = param1Plot(r);
|
||||
for c = 1:numel(param2Plot)
|
||||
P2 = param2Plot(c);
|
||||
|
||||
ax = nexttile((r-1)*numel(param2Plot) + c); hold(ax,'on');
|
||||
|
||||
% Find index of this (param1, param2)
|
||||
k = find(cellfun(@(v) all(abs(v - [P1 P2]) < 1e-6), scan_reference_values_plot), 1);
|
||||
if isempty(k), continue; end
|
||||
|
||||
% Extract g² curves for this pair
|
||||
G = results.g2_curves{k}; % [N_reps × Nθ]
|
||||
|
||||
% --- Plot all repetitions in light grey ---
|
||||
plot(ax, theta, G', 'Color', [0.7 0.7 0.7, 0.5]);
|
||||
|
||||
% --- Highlight every Nth repetition ---
|
||||
idx = Nhighlight:Nhighlight:size(G,1);
|
||||
for j = idx
|
||||
plot(ax, theta, G(j,:), 'Color', [0.3 0.3 0.3, 1], 'LineWidth', 1.5);
|
||||
end
|
||||
|
||||
% --- Mean + SEM shading ---
|
||||
mu = mean(G,1,'omitnan');
|
||||
se = std(G,0,1,'omitnan')/sqrt(size(G,1));
|
||||
fill(ax, [theta fliplr(theta)], [mu-se fliplr(mu+se)], [0.2 0.4 0.8], ...
|
||||
'FaceAlpha',0.2,'EdgeColor','none');
|
||||
|
||||
% --- Mean curve ---
|
||||
plot(ax, theta, mu, 'b-', 'LineWidth', 2);
|
||||
|
||||
% --- Vertical reference lines at pi/3 and 2pi/3 ---
|
||||
xlines = [1/3 2/3];
|
||||
for xl = xlines
|
||||
xline(ax, xl, 'k--', 'LineWidth', 1.5, 'Alpha', 0.5);
|
||||
end
|
||||
|
||||
% --- Axes formatting ---
|
||||
grid(ax,'on');
|
||||
xlabel(ax, '\theta / \pi', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
ylabel(ax, 'g^2(\theta)', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
title(ax, sprintf('%s=%.3g, %s=%.1f', opts.Param1Name, P1, opts.Param2Name, P2), ...
|
||||
'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
set(ax, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
end
|
||||
end
|
||||
|
||||
% --- Save figure ---
|
||||
if ~opts.SkipSaveFigures
|
||||
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
|
||||
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
|
||||
end
|
||||
end
|
118
Data-Analyzer/+Plotter/plotG2MeanHeatmap.m
Normal file
118
Data-Analyzer/+Plotter/plotG2MeanHeatmap.m
Normal file
@ -0,0 +1,118 @@
|
||||
function plotG2MeanHeatmap(results, theta_query, scan_parameter_values, scan_reference_values, varargin)
|
||||
%% plotG2MeanHeatmap: Plots a heatmap of mean g² values at a specified theta across the phase diagram
|
||||
%
|
||||
% Usage:
|
||||
% plotG2MeanHeatmap(results, pi/6, scan_parameter_values, scan_reference_values, ...
|
||||
% 'FigNum', 1, 'Colormap', @jet, 'CLim', [], 'ColorScale', 'linear', ...
|
||||
% 'XLabel', '\alpha (degrees)', 'YLabel', 'BField (G)', ...
|
||||
% 'Title', 'Mean g²', 'SaveFileName', 'g2MeanHeatmap.fig', ...
|
||||
% 'SaveDirectory', 'results', 'SkipSaveFigures', false);
|
||||
|
||||
% --- Parse optional inputs ---
|
||||
p = inputParser;
|
||||
addParameter(p, 'FigNum', []);
|
||||
addParameter(p, 'Colormap', @jet);
|
||||
addParameter(p, 'CLim', []);
|
||||
addParameter(p, 'ColorScale', 'linear', @(x) any(validatestring(x,{'linear','log'})));
|
||||
addParameter(p, 'XLabel', '\alpha (degrees)');
|
||||
addParameter(p, 'YLabel', 'BField (G)');
|
||||
addParameter(p, 'Title', 'Mean g²');
|
||||
addParameter(p, 'FontName', 'Arial');
|
||||
addParameter(p, 'FontSize', 14);
|
||||
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
||||
addParameter(p, 'SaveFileName', 'g2MeanHeatmap.fig', @ischar);
|
||||
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
||||
parse(p, varargin{:});
|
||||
opts = p.Results;
|
||||
|
||||
% --- Extract data at requested theta ---
|
||||
theta_vals = results.theta_values;
|
||||
[~, idx_theta] = min(abs(theta_vals - theta_query)); % closest index
|
||||
N_total = numel(results.g2_curves);
|
||||
dataCell = cell(N_total,1);
|
||||
for i = 1:N_total
|
||||
G = results.g2_curves{i}; % [N_reps × Nθ]
|
||||
dataCell{i} = G(:, idx_theta); % all repetitions at chosen theta
|
||||
end
|
||||
|
||||
% --- Convert reference/parameter values to numeric arrays ---
|
||||
scanRefArray = cell2mat(scan_reference_values(:)); % nParams × 2
|
||||
scanParamArray = cell2mat(scan_parameter_values(:)); % nTotal × 2
|
||||
|
||||
BFields = sort(unique(scanRefArray(:,1)), 'ascend'); % rows
|
||||
alphas = sort(unique(scanRefArray(:,2)), 'ascend'); % cols
|
||||
|
||||
nB = numel(BFields);
|
||||
nA = numel(alphas);
|
||||
|
||||
% --- Preallocate data matrix ---
|
||||
data_matrix = NaN(nB, nA);
|
||||
|
||||
% --- Fill matrix by looping over unique parameter pairs ---
|
||||
for k = 1:size(scanRefArray,1)
|
||||
B = scanRefArray(k,1);
|
||||
alpha = scanRefArray(k,2);
|
||||
|
||||
row = find(ismembertol(BFields, B, 1e-6));
|
||||
col = find(ismembertol(alphas, alpha, 1e-6));
|
||||
if isempty(row) || isempty(col), continue; end
|
||||
|
||||
repIdx = find(ismembertol(scanParamArray, [B alpha], 1e-6, 'ByRows', true));
|
||||
if isempty(repIdx), continue; end
|
||||
|
||||
% Extract mean g² across repetitions
|
||||
vals = cellfun(@(x) mean(x, 'omitnan'), dataCell(repIdx));
|
||||
data_matrix(row,col) = mean(vals, 'omitnan');
|
||||
end
|
||||
|
||||
% --- 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]);
|
||||
|
||||
% --- Plot heatmap ---
|
||||
imagesc(alphas, BFields, data_matrix);
|
||||
|
||||
set(gca, ...
|
||||
'FontName', opts.FontName, ...
|
||||
'FontSize', opts.FontSize, ...
|
||||
'YDir', 'normal', ...
|
||||
'ColorScale', opts.ColorScale); % linear or log
|
||||
|
||||
% --- Labels and title ---
|
||||
xlabel(opts.XLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
ylabel(opts.YLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
|
||||
% --- Compute fraction of pi ---
|
||||
theta_factor = theta_query / pi; % e.g., pi/6 -> 1/6
|
||||
|
||||
% --- Format as string ---
|
||||
if abs(round(1/theta_factor) - 1/theta_factor) < 1e-6 % e.g., 1/6
|
||||
theta_str = sprintf('\\pi/%d', round(1/theta_factor));
|
||||
elseif abs(theta_factor - round(theta_factor)) < 1e-6 % e.g., pi or 2*pi
|
||||
theta_str = sprintf('%d\\pi', round(theta_factor));
|
||||
else
|
||||
theta_str = sprintf('%.3g \\pi', theta_factor); % fallback numeric
|
||||
end
|
||||
|
||||
% --- Set title ---
|
||||
title(sprintf('%s | Mean g^{(2)}(\\delta\\theta) at \\delta\\theta = %s', opts.Title, theta_str), ...
|
||||
'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||
|
||||
% --- Colorbar ---
|
||||
colormap(feval(opts.Colormap));
|
||||
if ~isempty(opts.CLim)
|
||||
caxis(opts.CLim);
|
||||
end
|
||||
c = colorbar;
|
||||
|
||||
% --- Save figure ---
|
||||
if ~opts.SkipSaveFigures
|
||||
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
|
||||
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
|
||||
end
|
||||
end
|
@ -118,7 +118,7 @@ function plotG2PDF(results, theta_query, varargin)
|
||||
end
|
||||
|
||||
% --- Set title ---
|
||||
title(sprintf('%s | g^{(2)}(\\delta\\theta) at \\theta = %s', opts.Title, theta_str), ...
|
||||
title(sprintf('%s | g^{(2)}(\\delta\\theta) at \\delta\\theta = %s', opts.Title, theta_str), ...
|
||||
'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||
|
||||
colormap(feval(opts.Colormap));
|
||||
|
@ -1,9 +1,10 @@
|
||||
function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
||||
function plotHeatmap(results, scan_parameter_values, scan_reference_values, fieldName, varargin)
|
||||
%% plotHeatmap: Plots a heatmap for a field in a struct array.
|
||||
%
|
||||
% Usage:
|
||||
% plotHeatmap(results_all, x_values, y_values, fieldName, ...
|
||||
% plotHeatmap(results, scan_parameter_values, scan_reference_values, 'energy', ...
|
||||
% 'FigNum', 1, 'Colormap', parula, 'CLim', [0 1], ...
|
||||
% 'ColorScale', 'log', ...
|
||||
% 'XLabel', '\alpha (degrees)', 'YLabel', 'BField (G)', ...
|
||||
% 'Title', 'My Title', 'SaveFileName', 'heatmap.fig', ...
|
||||
% 'SaveDirectory', 'results', 'SkipSaveFigures', false);
|
||||
@ -13,6 +14,7 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
||||
addParameter(p, 'FigNum', []);
|
||||
addParameter(p, 'Colormap', parula);
|
||||
addParameter(p, 'CLim', []);
|
||||
addParameter(p, 'ColorScale', 'linear', @(x) any(validatestring(x,{'linear','log'}))); % NEW
|
||||
addParameter(p, 'XLabel', '\alpha (degrees)');
|
||||
addParameter(p, 'YLabel', 'BField (G)');
|
||||
addParameter(p, 'Title', fieldName);
|
||||
@ -24,17 +26,32 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
||||
parse(p, varargin{:});
|
||||
opts = p.Results;
|
||||
|
||||
N_y = length(results_all);
|
||||
N_x = length(x_values);
|
||||
% --- Convert reference/parameter values to numeric arrays ---
|
||||
scanRefArray = cell2mat(scan_reference_values(:)); % nParams × 2
|
||||
scanParamArray = cell2mat(scan_parameter_values(:)); % nTotal × 2
|
||||
|
||||
BFields = sort(unique(scanRefArray(:,1)), 'ascend'); % rows
|
||||
alphas = sort(unique(scanRefArray(:,2)), 'ascend'); % cols
|
||||
nB = numel(BFields);
|
||||
nA = numel(alphas);
|
||||
|
||||
% --- Preallocate data matrix ---
|
||||
data_matrix = NaN(N_y, N_x);
|
||||
for i = 1:N_y
|
||||
if isfield(results_all(i), fieldName)
|
||||
data_matrix(i, :) = results_all(i).(fieldName);
|
||||
else
|
||||
warning('Field "%s" does not exist in results_all(%d). Filling with NaN.', fieldName, i);
|
||||
end
|
||||
data_matrix = NaN(nB, nA);
|
||||
|
||||
% --- Fill matrix by looping over unique parameter pairs ---
|
||||
for k = 1:size(scanRefArray,1)
|
||||
B = scanRefArray(k,1);
|
||||
alpha = scanRefArray(k,2);
|
||||
|
||||
row = find(ismembertol(BFields, B, 1e-6));
|
||||
col = find(ismembertol(alphas, alpha, 1e-6));
|
||||
if isempty(row) || isempty(col), continue; end
|
||||
|
||||
repIdx = find(ismembertol(scanParamArray, [B alpha], 1e-6, 'ByRows', true));
|
||||
if isempty(repIdx), continue; end
|
||||
|
||||
vals = results.(fieldName)(repIdx);
|
||||
data_matrix(row,col) = mean(vals, 'omitnan');
|
||||
end
|
||||
|
||||
% --- Create figure ---
|
||||
@ -44,20 +61,24 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
||||
fig = figure(opts.FigNum);
|
||||
end
|
||||
clf(fig);
|
||||
set(fig, 'Color', 'w', 'Position', [50 50 950 750]);
|
||||
set(fig, 'Color', 'w', 'Position', [100 100 950 750]);
|
||||
|
||||
% --- Plot heatmap ---
|
||||
imagesc(x_values, y_values, data_matrix);
|
||||
colormap(opts.Colormap);
|
||||
imagesc(alphas, BFields, data_matrix);
|
||||
colormap(feval(opts.Colormap));
|
||||
if ~isempty(opts.CLim)
|
||||
caxis(opts.CLim);
|
||||
end
|
||||
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize, 'YDir', 'normal');
|
||||
set(gca, ...
|
||||
'FontName', opts.FontName, ...
|
||||
'FontSize', opts.FontSize, ...
|
||||
'YDir', 'normal', ...
|
||||
'ColorScale', opts.ColorScale); % <-- linear or log
|
||||
|
||||
% --- Labels and title ---
|
||||
xlabel(opts.XLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
ylabel(opts.YLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
title(opts.Title, 'Interpreter', 'latex', 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||
title(opts.Title, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||
colorbar;
|
||||
|
||||
% --- Save figure ---
|
||||
@ -65,5 +86,4 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
||||
'SaveFileName', opts.SaveFileName, ...
|
||||
'SaveDirectory', opts.SaveDirectory, ...
|
||||
'SkipSaveFigures', opts.SkipSaveFigures);
|
||||
|
||||
end
|
||||
end
|
@ -100,9 +100,9 @@ function plotPDF(dataCell, referenceValues, varargin)
|
||||
ylabel(c, 'PDF', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
else
|
||||
if opts.NormalizeHistogram
|
||||
ylabel(c, 'Probability Density', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
ylabel(c, 'Probability Density', 'Rotation', -90, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
else
|
||||
ylabel(c, 'Counts', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||
ylabel(c, 'Counts', 'FontName', 'Rotation', -90, opts.FontName, 'FontSize', opts.FontSize);
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
%% --- User chooses which dataset to load ---
|
||||
datasetIdx = 6; % <-- change this to 1, 2, 3, ...
|
||||
datasetIdx = 1; % <-- change this to 1, 2, 3, ...
|
||||
datasetName = sprintf('Dataset_%d', datasetIdx);
|
||||
|
||||
% --- Base directory selection ---
|
||||
|
@ -91,9 +91,6 @@ end
|
||||
[od_imgs, scan_parameter_values, scan_reference_values, ~] = Helper.collectODImages(options);
|
||||
|
||||
% === Plot raw images ===
|
||||
n_total = numel(scan_parameter_values);
|
||||
nParams = numel(scan_reference_values);
|
||||
nReps = n_total/nParams;
|
||||
|
||||
% Select every 10th repetition
|
||||
selected_reps = [1, 10, 20, 30, 40, 50];
|
||||
|
@ -1,32 +1,99 @@
|
||||
BFieldRange = [2.45 2.44 2.43 2.42 2.40 2.39 2.38 2.37 2.36 2.35 2.34 2.32 2.30 2.28 2.25 2.20 2.15 2.10 2.05 2.00 1.95 1.90 1.85 1.80];
|
||||
AlphaRange = [180 175 170 168 166 164 162 160 158 156 154 152 150 145 140];
|
||||
%% --- User chooses which dataset to load ---
|
||||
datasetIdx = 1; % <-- change this to 1, 2, 3, ...
|
||||
datasetName = sprintf('Dataset_%d', datasetIdx);
|
||||
|
||||
% Z must be 15x24 to match y-by-x
|
||||
Z = zeros([numel(BFieldRange), numel(AlphaRange)]);... % your data
|
||||
% --- Base directory selection ---
|
||||
useLocalBaseDir = false; % <-- set true to use script location, false to use manual path
|
||||
|
||||
[X,Y] = meshgrid(x, y);
|
||||
if useLocalBaseDir
|
||||
% Use folder where this script is located
|
||||
thisScriptPath = mfilename('fullpath');
|
||||
[thisScriptDir, ~, ~] = fileparts(thisScriptPath);
|
||||
baseDir = fullfile(thisScriptDir, 'Results');
|
||||
else
|
||||
% Use manually specified folder
|
||||
% baseDir = 'E:\Results - Experiment\202508\BECToDropletsToStripes\';
|
||||
baseDir = 'C:\Users\Karthik-OfficePC\Documents\GitRepositories\Calculations\Data-Analyzer\+Scripts\PhaseDiagram\Results';
|
||||
end
|
||||
|
||||
% --- Build paths ---
|
||||
dataFile = fullfile(baseDir, 'SavedData', [datasetName '.mat']);
|
||||
figSaveDir = fullfile(baseDir, 'SavedFigures', datasetName);
|
||||
|
||||
% --- Load dataset ---
|
||||
data = load(dataFile);
|
||||
|
||||
% --- Ensure figure folder exists ---
|
||||
if ~exist(figSaveDir, 'dir')
|
||||
mkdir(figSaveDir);
|
||||
end
|
||||
|
||||
% --- Access dataset struct dynamically ---
|
||||
datasetStruct = data.(datasetName);
|
||||
compiled_results = datasetStruct.results;
|
||||
scan_parameter_values = datasetStruct.scan_parameter_values;
|
||||
scan_reference_values = datasetStruct.scan_reference_values;
|
||||
|
||||
% --- Load options used during analysis ---
|
||||
options = datasetStruct.options;
|
||||
options.font = 'Bahnschrift'; % override if needed
|
||||
options.skipSaveFigures = false; % override if needed
|
||||
|
||||
%% ------------------ Plot Heatmaps ------------------
|
||||
|
||||
% Heatmap of radial_spectral_contrast
|
||||
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'radial_spectral_contrast', ...
|
||||
'Colormap', @sky, ...
|
||||
'CLim', [0 0.008], ...
|
||||
Plotter.plotHeatmap(compiled_results.spectral_analysis_results, scan_parameter_values, scan_reference_values, 'radial_spectral_contrast', ...
|
||||
'Colormap', @Colormaps.coolwarm, ...
|
||||
'ColorScale', 'log', ...
|
||||
'XLabel', '\alpha (degrees)', ...
|
||||
'YLabel', 'BField (G)', ...
|
||||
'Title', 'Radial Spectral Contrast', ...
|
||||
'FigNum', 10, ...
|
||||
'FontName', options.font, ...
|
||||
'FigNum', 9, ...
|
||||
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
|
||||
'SaveDirectory', options.saveDirectory);
|
||||
|
||||
% Heatmap of mean_max_g2_values
|
||||
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'mean_max_g2_values', ...
|
||||
'Colormap', @sky, ...
|
||||
'CLim', [0 1], ...
|
||||
%% Heatmap of mean_max_g2_values
|
||||
Plotter.plotHeatmap(compiled_results.custom_g_results, scan_parameter_values, scan_reference_values, 'mean_max_g2', ...
|
||||
'Colormap', @Colormaps.coolwarm, ...
|
||||
'ColorScale', 'linear', ...
|
||||
'XLabel', '\alpha (degrees)', ...
|
||||
'YLabel', 'BField (G)', ...
|
||||
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
||||
'FigNum', 9, ...
|
||||
'FontName', options.font, ...
|
||||
'FigNum', 10, ...
|
||||
'SaveFileName', 'Heatmap_MaxG2.fig', ...
|
||||
'SaveDirectory', options.saveDirectory);
|
||||
|
||||
%% Heatmap of mean g2 values as specific theta
|
||||
|
||||
Plotter.plotG2MeanHeatmap(compiled_results.full_g2_results, pi/2, ...
|
||||
scan_parameter_values, scan_reference_values, ...
|
||||
'Colormap', @Colormaps.coolwarm, ...
|
||||
'CLim', [0 1.0], ...
|
||||
'ColorScale', 'log', ...
|
||||
'XLabel', '\alpha (degrees)', ...
|
||||
'YLabel', 'BField (G)', ...
|
||||
'Title', options.titleString, ...
|
||||
'FontName', options.font, ...
|
||||
'FigNum', 11, ...
|
||||
'SaveFileName', 'Heatmap_MeanG2.fig', ...
|
||||
'SaveDirectory', options.saveDirectory);
|
||||
|
||||
%% G2 curves across phase diagram
|
||||
|
||||
Plotter.plotG2CurvesMultiParam(compiled_results.full_g2_results, ...
|
||||
scan_parameter_values, scan_reference_values, ...
|
||||
[2.45, 2.35, 2.32, 2.28], ...
|
||||
[0, 10, 20, 30, 40], ...
|
||||
'FigNum', 12, ...
|
||||
'FontName', options.font, ...
|
||||
'FontSize', 14, ...
|
||||
'Title', options.titleString, ...
|
||||
'Param1Name', 'B', ...
|
||||
'Param2Name', '\alpha', ...
|
||||
'HighlightEvery', 5, ...
|
||||
'SkipSaveFigures', false, ...
|
||||
'SaveFileName', 'G2Curves_PhaseDiagram.fig', ...
|
||||
'SaveDirectory', options.saveDirectory);
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
dataSources = {
|
||||
struct('sequence', 'StructuralPhaseTransition', ...
|
||||
'date', '2025/08/20', ...
|
||||
'runs', [2]) % specify run numbers as a string in "" or just as a numeric value
|
||||
'runs', [1]) % specify run numbers as a string in "" or just as a numeric value
|
||||
};
|
||||
|
||||
options = struct();
|
||||
@ -56,7 +56,7 @@ options.skipFullODImagesFolderUse = false;
|
||||
options.skipSaveData = false;
|
||||
options.skipSaveFigures = true;
|
||||
options.skipSaveProcessedOD = true;
|
||||
options.skipLivePlot = true;
|
||||
options.skipLivePlot = false;
|
||||
options.showProgressBar = true;
|
||||
|
||||
% Extras
|
||||
|
215
Data-Analyzer/+Scripts/PhaseDiagram/plotODImageGrid.m
Normal file
215
Data-Analyzer/+Scripts/PhaseDiagram/plotODImageGrid.m
Normal file
@ -0,0 +1,215 @@
|
||||
%% ===== BEC-Droplets-Stripes Settings =====
|
||||
|
||||
% Specify data location to run analysis on
|
||||
dataSources = {
|
||||
struct('sequence', 'StructuralPhaseTransition', ...
|
||||
'date', '2025/08/20', ...
|
||||
'runs', [1]) % specify run numbers as a string in "" or just as a numeric value
|
||||
};
|
||||
|
||||
options = struct();
|
||||
|
||||
% File paths
|
||||
options.baseDataFolder = '//DyLabNAS/Data';
|
||||
options.FullODImagesFolder = 'E:/Data - Experiment/FullODImages/202508';
|
||||
options.measurementName = 'DropletsToStripes';
|
||||
scriptFullPath = mfilename('fullpath');
|
||||
options.saveDirectory = fileparts(scriptFullPath);
|
||||
|
||||
% Camera / imaging settings
|
||||
options.cam = 4; % 1 - ODT_1_Axis_Camera; 2 - ODT_2_Axis_Camera; 3 - Horizontal_Axis_Camera;, 4 - Vertical_Axis_Camera;
|
||||
options.angle = 0; % angle by which image will be rotated
|
||||
options.center = [1420, 2050];
|
||||
options.span = [200, 200];
|
||||
options.fraction = [0.1, 0.1];
|
||||
options.pixel_size = 5.86e-6; % in meters
|
||||
options.magnification = 24.6;
|
||||
options.ImagingMode = 'HighIntensity';
|
||||
options.PulseDuration = 5e-6; % in s
|
||||
|
||||
% Fourier analysis settings
|
||||
options.theta_min = deg2rad(0);
|
||||
options.theta_max = deg2rad(180);
|
||||
options.N_radial_bins = 500;
|
||||
options.Radial_Sigma = 2;
|
||||
options.Radial_WindowSize = 5; % odd number
|
||||
|
||||
options.k_min = 1.2771; % μm⁻¹
|
||||
options.k_max = 2.5541; % μm⁻¹
|
||||
options.N_angular_bins = 180;
|
||||
options.Angular_Threshold = 75;
|
||||
options.Angular_Sigma = 2;
|
||||
options.Angular_WindowSize = 5;
|
||||
options.zoom_size = 50;
|
||||
|
||||
% Flags
|
||||
options.skipUnshuffling = false;
|
||||
options.skipNormalization = false;
|
||||
|
||||
options.skipFringeRemoval = true;
|
||||
options.skipPreprocessing = true;
|
||||
options.skipMasking = true;
|
||||
options.skipIntensityThresholding = true;
|
||||
options.skipBinarization = true;
|
||||
|
||||
options.skipFullODImagesFolderUse = false;
|
||||
options.skipSaveData = false;
|
||||
options.skipSaveFigures = true;
|
||||
options.skipSaveProcessedOD = true;
|
||||
options.skipLivePlot = false;
|
||||
options.showProgressBar = true;
|
||||
|
||||
% Extras
|
||||
options.font = 'Bahnschrift';
|
||||
switch options.measurementName
|
||||
case 'DropletsToStripes'
|
||||
options.ignore_scan_parameter = {'ps_rot_mag_field'}; % Parameter to IGNORE from these - rot_mag_field, ps_rot_mag_field, ps_rot_mag_fin_pol_angle
|
||||
options.flipSortOrder = true;
|
||||
options.scanParameterUnits = {'gauss','degrees'};
|
||||
options.titleString = 'Droplets to Stripes';
|
||||
case 'StripesToDroplets'
|
||||
options.ignore_scan_parameter = {'ps_rot_mag_field'}; % Parameter to IGNORE from these - rot_mag_field, ps_rot_mag_field, ps_rot_mag_fin_pol_angle
|
||||
options.flipSortOrder = false;
|
||||
options.scanParameterUnits = {'gauss','degrees'};
|
||||
options.titleString = 'Stripes to Droplets';
|
||||
end
|
||||
|
||||
%% ===== Collect Images and Launch Viewer =====
|
||||
|
||||
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
|
||||
|
||||
[od_imgs, scan_parameter_values, scan_reference_values, ~] = Helper.collectODImages(options);
|
||||
|
||||
%% === Plot raw images ===
|
||||
|
||||
% === User selection of BFields and alpha values ===
|
||||
BFieldsToPlot = [2.45, 2.4, 2.35, 2.34, 2.32, 2.3, 2.28]; % [2.45, 2.44, 2.43, 2.42, 2.4, 2.39, 2.38, 2.37, 2.36, 2.35, 2.34, 2.32, 2.3, 2.28, 2.25, 2.2, 2.15, 2.1, 2.05, 2.0, 1.95, 1.90, 1.85, 1.8] G
|
||||
alphasToPlot = [0, 5, 10, 20, 30, 40]; % [0, 5, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 35, 40] degrees
|
||||
|
||||
% --- Convert scan_reference_values (cell array of 1x2) into Nx2 array ---
|
||||
scanRefArray = cell2mat(scan_reference_values(:)); % Nx2
|
||||
scanParamArray = cell2mat(scan_parameter_values(:)); % Nx2
|
||||
|
||||
BFieldVals = scanRefArray(:,1);
|
||||
alphaVals = scanRefArray(:,2);
|
||||
|
||||
% --- Select subset of scan_reference_values to plot ---
|
||||
keepIdx = ismembertol(BFieldVals, BFieldsToPlot, 1e-6) & ...
|
||||
ismembertol(alphaVals, alphasToPlot, 1e-6);
|
||||
|
||||
scan_reference_values_plot = scan_reference_values(keepIdx);
|
||||
nParamsPlot = numel(scan_reference_values_plot);
|
||||
|
||||
% --- Warn about missing values ---
|
||||
existingB = BFieldsToPlot(ismembertol(BFieldsToPlot, unique(BFieldVals), 1e-6));
|
||||
missingB = setdiff(BFieldsToPlot, existingB);
|
||||
|
||||
existingA = alphasToPlot(ismembertol(alphasToPlot, unique(alphaVals), 1e-6));
|
||||
missingA = setdiff(alphasToPlot, existingA);
|
||||
|
||||
if ~isempty(missingB)
|
||||
warning('The following BFields were not found: %s', num2str(missingB));
|
||||
end
|
||||
if ~isempty(missingA)
|
||||
warning('The following alpha values were not found: %s', num2str(missingA));
|
||||
end
|
||||
|
||||
BFieldsPlot = existingB;
|
||||
alphasPlot = existingA;
|
||||
|
||||
% --- Collect all repetitions for each kept parameter ---
|
||||
od_imgs_grouped = cell(nParamsPlot, 1);
|
||||
|
||||
for k = 1:nParamsPlot
|
||||
paramVal = scan_reference_values_plot{k}; % 1x2 vector [BField, alpha]
|
||||
|
||||
% Find all repetitions matching this parameter pair (BField, alpha)
|
||||
repIdx = find(ismembertol(scanParamArray, paramVal, 1e-6, 'ByRows', true));
|
||||
|
||||
% Store images + parameter values
|
||||
od_imgs_grouped{k} = od_imgs(repIdx);
|
||||
end
|
||||
|
||||
% === Plot OD images as a phase diagram ===
|
||||
% Unique values for axes
|
||||
BFieldsPlot = sort(unique(cellfun(@(c) c(1), scan_reference_values_plot)), 'descend'); % y-axis
|
||||
alphasPlot = sort(unique(cellfun(@(c) c(2), scan_reference_values_plot))); % x-axis
|
||||
|
||||
nB = numel(BFieldsPlot);
|
||||
nA = numel(alphasPlot);
|
||||
|
||||
repToPlot = 1; % which repetition to show
|
||||
|
||||
% Create figure
|
||||
figure(300); clf;
|
||||
set(gcf, 'Position', [100 100 950 750]);
|
||||
t = tiledlayout(nB, nA, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||
|
||||
font = 'Bahnschrift';
|
||||
allAxes = gobjects(nB, nA);
|
||||
|
||||
% Loop over rows (BFields) and columns (alphas)
|
||||
for r = 1:nB
|
||||
B = BFieldsPlot(r);
|
||||
for c = 1:nA
|
||||
alpha = alphasPlot(c);
|
||||
|
||||
ax = nexttile((r-1)*nA + c);
|
||||
allAxes(r,c) = ax;
|
||||
|
||||
% Find the index k corresponding to this (BField, alpha) pair
|
||||
k = find(cellfun(@(v) all(abs(v - [B alpha]) < 1e-6), scan_reference_values_plot), 1);
|
||||
|
||||
if ~isempty(k)
|
||||
img = od_imgs_grouped{k}{repToPlot};
|
||||
imagesc(ax, img);
|
||||
else
|
||||
% If missing, leave blank
|
||||
axis(ax, 'off');
|
||||
continue
|
||||
end
|
||||
|
||||
set(ax, 'YDir', 'normal');
|
||||
axis(ax, 'image');
|
||||
ax.DataAspectRatioMode = 'manual';
|
||||
ax.PlotBoxAspectRatioMode = 'auto';
|
||||
ax.XTick = [];
|
||||
ax.YTick = [];
|
||||
colormap(ax, Colormaps.inferno());
|
||||
end
|
||||
end
|
||||
|
||||
% Shared colorbar
|
||||
cb = colorbar('Location', 'eastoutside');
|
||||
ylabel(cb, 'Optical Density');
|
||||
cb.Layout.Tile = 'east';
|
||||
cb.FontName = font;
|
||||
cb.FontSize = 18;
|
||||
cb.Label.FontSize = 20;
|
||||
cb.Label.Rotation = -90;
|
||||
cb.Label.VerticalAlignment = 'bottom';
|
||||
cb.Label.HorizontalAlignment = 'center';
|
||||
cb.Direction = 'normal';
|
||||
|
||||
% Label alpha values along bottom
|
||||
for c = 1:nA
|
||||
ax = allAxes(end, c);
|
||||
ax.XTick = size(img,2)/2;
|
||||
ax.XTickLabel = sprintf('%.0f°', alphasPlot(c));
|
||||
ax.XTickLabelRotation = 45;
|
||||
ax.FontName = font;
|
||||
ax.FontSize = 16;
|
||||
end
|
||||
|
||||
% Label BFields along left
|
||||
for r = 1:nB
|
||||
ax = allAxes(r, 1);
|
||||
ax.YTick = size(img,1)/2;
|
||||
ax.YTickLabel = sprintf('%.2f G', BFieldsPlot(r));
|
||||
ax.FontName = font;
|
||||
ax.FontSize = 16;
|
||||
end
|
||||
|
||||
% Figure title
|
||||
title(t, sprintf('%s', options.titleString), ...
|
||||
'FontSize', 24, 'FontName', font, 'FontWeight', 'bold');
|
Loading…
Reference in New Issue
Block a user