function selectPhaseDiagramPoints(PhaseDiagramMatrix, NumberOfAtoms, ScatteringLengths, savePath) % Interactive point selector for phase diagram. % - Single click to select a point (plotted in red) % - Double click to remove nearest point % - Save points to a MAT file using savePath xlen = length(NumberOfAtoms); ylen = length(ScatteringLengths); selectedIndices = []; selectedValues = []; plottedPoints = []; % handles of plotted markers % Create figure and axes fig = figure('Name', 'Interactive Phase Diagram', 'Position', [100, 100, 1600, 900]); ax = axes(fig); imagesc(ax, PhaseDiagramMatrix); set(ax, 'YDir', 'normal'); colormap(ax, parula); colorbar(ax); axis(ax, 'equal', 'tight'); hold(ax, 'on'); % This is crucial! % Style set(ax, 'FontSize', 16, 'Box', 'On', 'Linewidth', 2); xticks(ax, 1:xlen); yticks(ax, 1:ylen); xticklabels(ax, string(NumberOfAtoms)); yticklabels(ax, string(ScatteringLengths)); xlabel(ax, 'Number of Atoms', 'FontSize', 16); ylabel(ax, 'Scattering Length (\times a_o)', 'FontSize', 16); grid(ax, 'on'); % Save Button uicontrol('Style', 'pushbutton', ... 'String', 'Save Points', ... 'FontSize', 12, ... 'Position', [20 20 120 40], ... 'Callback', @savePoints); % Set callback on axes, not on image fig.WindowButtonDownFcn = @handleClick; selectedIndices = zeros(0, 2); % ← ensure it's Nx2, not just [] selectedValues = zeros(0, 2); plottedPoints = gobjects(0); % empty graphics array function handleClick(~, ~) try clickType = get(fig, 'SelectionType'); cp = get(ax, 'CurrentPoint'); xClick = round(cp(1, 1)); yClick = round(cp(1, 2)); if xClick < 1 || xClick > xlen || yClick < 1 || yClick > ylen return; end if strcmp(clickType, 'normal') % Single click = add point alreadySelected = any(ismember(selectedIndices, [xClick, yClick], 'rows')); if ~alreadySelected selectedIndices(end+1, :) = [xClick, yClick]; selectedValues(end+1, :) = [NumberOfAtoms(xClick), ScatteringLengths(yClick)]; h = plot(ax, xClick, yClick, 'r*', 'MarkerSize', 10, 'LineWidth', 1.5); plottedPoints(end+1) = h; fprintf('Selected: N = %.2f, a = %.2f\n', NumberOfAtoms(xClick), ScatteringLengths(yClick)); end elseif strcmp(clickType, 'open') % Double click = remove point if isempty(selectedIndices), return; end dists = vecnorm(selectedIndices - [xClick, yClick], 2, 2); [minDist, idx] = min(dists); if minDist <= 1 fprintf('Removed: N = %.2f, a = %.2f\n', selectedValues(idx,1), selectedValues(idx,2)); delete(plottedPoints(idx)); selectedIndices(idx, :) = []; selectedValues(idx, :) = []; plottedPoints(idx) = []; end end catch ME fprintf('Error in handleClick:\n%s\n', getReport(ME, 'extended')); end end function savePoints(~, ~) if isempty(selectedValues) warndlg('No points selected.', 'Save Warning'); return; end SelectedPoints.indices = selectedIndices; SelectedPoints.values = selectedValues; save(savePath, 'SelectedPoints'); msgbox(sprintf('Saved %d points to:\n%s', size(selectedValues,1), savePath), 'Saved'); end end