fix(matlab): adopt user's compact plot layout for all variations
Port the unmerge_d0_5 fix (b6dc69c) into variation_plot.m: tight centred plot
box (Position [0.2 0.30 0.60 0.60]), TickDir out, and xticklabels('auto') --
which keeps x labels horizontal when they fit (<=~10 days) and auto-rotates
them when crowded (e.g. 14-day windows). Replaces the manual rotated-text hack.
Regenerated all learning-curve figures; removed the stray plotcurve.asv and
gitignored *.asv.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -29,3 +29,4 @@ playwright-report/
|
|||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
*.asv
|
||||||
|
|||||||
@@ -38,21 +38,12 @@ legend([e1 e2], {sprintf('anodal, N = %d', na), sprintf('control, N = %d', nc)},
|
|||||||
'Location', 'northwest', 'Box', 'off');
|
'Location', 'northwest', 'Box', 'off');
|
||||||
xlabel('training day'); ylabel(ylab);
|
xlabel('training day'); ylabel(ylab);
|
||||||
title(vname, 'Interpreter', 'none');
|
title(vname, 'Interpreter', 'none');
|
||||||
% Vertical x-axis tick labels. XTickLabelRotation / xtickangle are NOT honored
|
% Compact publication layout with a tight centred plot box and ticks pointing
|
||||||
% by exportgraphics on a headless invisible figure, so draw the labels manually
|
% out. Setting XTickLabel {} then xticklabels('auto') resets the labels cleanly
|
||||||
% as rotated text objects (which always render).
|
% after the Position change.
|
||||||
set(gca, 'XTick', xd, 'XTickLabel', {}, 'Position', [0.13 0.20 0.80 0.70], ...
|
set(gca, 'XTick', xd, 'XTickLabel', {}, 'Position', [0.2 0.30 0.60 0.60], ...
|
||||||
'FontName', 'Arial', 'FontSize', 13, 'LineWidth', 1.5, 'Box', 'off');
|
'FontName', 'Arial', 'FontSize', 13, 'LineWidth', 1.5, 'Box', 'off', 'TickDir', 'out');
|
||||||
drawnow;
|
xticklabels('auto')
|
||||||
yl = ylim(gca);
|
|
||||||
yb = yl(1) - 0.015 * (yl(2) - yl(1));
|
|
||||||
for k = 1:numel(xd)
|
|
||||||
text(xd(k), yb, num2str(xd(k)), 'Parent', gca, 'Rotation', 90, ...
|
|
||||||
'HorizontalAlignment', 'right', 'VerticalAlignment', 'middle', ...
|
|
||||||
'FontName', 'Arial', 'FontSize', 13, 'Clipping', 'off');
|
|
||||||
end
|
|
||||||
xlh = get(gca, 'XLabel'); % push the axis label below the vertical ticks
|
|
||||||
set(xlh, 'Units', 'normalized', 'Position', [0.5 -0.15 0]);
|
|
||||||
drawnow;
|
drawnow;
|
||||||
exportgraphics(fig, outFile, 'Resolution', 150);
|
exportgraphics(fig, outFile, 'Resolution', 150);
|
||||||
close(fig);
|
close(fig);
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
% Variation learning-curve plots, in the style of the paper:
|
|
||||||
% "Lines indicate mean (and SEM) across animals in the anodal (red) and
|
|
||||||
% control (blue) groups."
|
|
||||||
% Produces TWO figures from this folder's data.csv:
|
|
||||||
% learning_curve.png # successes (count) per training day
|
|
||||||
% learning_curve_rate.png success rate (success/attempts) per training day
|
|
||||||
% anodal / treatment = stim 1 (red); control = stim 0 (blue). Per-group N is
|
|
||||||
% read from the data. Training day is 1-indexed (our day 0 = paper "Day 1") and
|
|
||||||
% the x-axis tick labels are drawn vertically.
|
|
||||||
% Run: matlab -batch "plotcurve"
|
|
||||||
% (Copy of analysis/matlab/variation_plot.m; see make_variation_plot.m.)
|
|
||||||
|
|
||||||
here = fileparts(mfilename('fullpath'));
|
|
||||||
if isempty(here); here = pwd; end
|
|
||||||
vname = regexprep(here, '.*[/\\]', '');
|
|
||||||
|
|
||||||
D = readtable(fullfile(here, 'data.csv'), 'TextType', 'string');
|
|
||||||
days = unique(D.day);
|
|
||||||
xd = days + 1; % plot as 1-indexed training day (paper axis)
|
|
||||||
red = [0.85 0.10 0.10];
|
|
||||||
blue = [0.10 0.30 0.85];
|
|
||||||
|
|
||||||
localPlot(D, days, xd, 'count', '# successes', ...
|
|
||||||
fullfile(here, 'learning_curve.png'), vname, red, blue);
|
|
||||||
localPlot(D, days, xd, 'rate', 'success rate', ...
|
|
||||||
fullfile(here, 'learning_curve_rate.png'), vname, red, blue);
|
|
||||||
|
|
||||||
% ------------------------------------------------------------------ helpers
|
|
||||||
function localPlot(D, days, xd, metric, ylab, outFile, vname, red, blue)
|
|
||||||
[Ma, Sa, na] = localCurve(D, 1, days, metric); % anodal / treatment
|
|
||||||
[Mc, Sc, nc] = localCurve(D, 0, days, metric); % control
|
|
||||||
fig = figure('Visible', 'off', 'Color', 'w', 'Position', [100 100 560 460]);
|
|
||||||
hold on
|
|
||||||
e1 = errorbar(xd, Ma, Sa, '-o', 'Color', red, 'MarkerFaceColor', red, 'LineWidth', 2);
|
|
||||||
e2 = errorbar(xd, Mc, Sc, '-o', 'Color', blue, 'MarkerFaceColor', blue, 'LineWidth', 2);
|
|
||||||
hold off
|
|
||||||
legend([e1 e2], {sprintf('anodal, N = %d', na), sprintf('control, N = %d', nc)}, ...
|
|
||||||
'Location', 'northwest', 'Box', 'off');
|
|
||||||
xlabel('training day'); ylabel(ylab);
|
|
||||||
title(vname, 'Interpreter', 'none');
|
|
||||||
|
|
||||||
set(gca, 'XTick', xd, 'XTickLabel', {}, 'Position', [0.13 0.20 0.80 0.70], ...
|
|
||||||
'FontName', 'Arial', 'FontSize', 13, 'LineWidth', 1.5, 'Box', 'off', 'TickDir', 'out');
|
|
||||||
drawnow;
|
|
||||||
yl = ylim(gca);
|
|
||||||
yb = yl(1) - 0.015 * (yl(2) - yl(1));
|
|
||||||
for k = 1:numel(xd)
|
|
||||||
text(xd(k), yb, num2str(xd(k)), 'Parent', gca, ...
|
|
||||||
'HorizontalAlignment', 'right', 'VerticalAlignment', 'middle', ...
|
|
||||||
'FontName', 'Arial', 'FontSize', 13, 'Clipping', 'off');
|
|
||||||
end
|
|
||||||
xlh = get(gca, 'XLabel'); % push the axis label below the vertical ticks
|
|
||||||
set(xlh, 'Units', 'normalized', 'Position', [0.5 -0.15 0]);
|
|
||||||
drawnow;
|
|
||||||
exportgraphics(fig, outFile, 'Resolution', 150);
|
|
||||||
close(fig);
|
|
||||||
fprintf('%s: wrote %s (anodal N=%d, control N=%d)\n', vname, outFile, na, nc);
|
|
||||||
end
|
|
||||||
|
|
||||||
function [M, S, n] = localCurve(D, stimVal, days, metric)
|
|
||||||
%LOCALCURVE Per-day mean and SEM across the animals in a group, for a metric.
|
|
||||||
subs = unique(D.subject(D.stim == stimVal));
|
|
||||||
n = numel(subs);
|
|
||||||
X = nan(numel(days), n);
|
|
||||||
for j = 1:n
|
|
||||||
for i = 1:numel(days)
|
|
||||||
r = D.subject == subs(j) & D.day == days(i);
|
|
||||||
if ~any(r); continue; end
|
|
||||||
if strcmp(metric, 'rate')
|
|
||||||
tot = sum(D.total(r));
|
|
||||||
if tot > 0; X(i, j) = sum(D.success(r)) / tot; end
|
|
||||||
else
|
|
||||||
X(i, j) = mean(D.success(r));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
M = mean(X, 2, 'omitnan');
|
|
||||||
S = std(X, [], 2, 'omitnan') ./ sqrt(sum(~isnan(X), 2));
|
|
||||||
end
|
|
||||||
Reference in New Issue
Block a user