Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions FitResSummary.m
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,12 @@ function setCoeffRange(frsObj,minVal,maxVal)
xticklabel_rotate([],90,[],'Fontsize',10);%rotateticklabel(gca,-90);
end

if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(h);
catch
end
end
end
function handle = plot3dCoeffSummary(frsObj,h)
% handle = plot3dCoeffSummary(frsObj,h)
Expand Down Expand Up @@ -605,6 +611,12 @@ function setCoeffRange(frsObj,minVal,maxVal)
h= legend; set(h,'Location','BestOutside'); ylabel(''); xlabel(''); title('');
end
end
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(handle);
catch
end
end
end

function handle = plotSummary(frsObj)
Expand Down Expand Up @@ -636,6 +648,12 @@ function setCoeffRange(frsObj,minVal,maxVal)
set([hx hy],'FontName', 'Arial','FontSize',11,'FontWeight','bold');
title('Change in BIC Across Neurons','FontWeight','bold','FontSize',11,'FontName','Arial');
set(gca,'XTickLabelRotation',90);
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(handle);
catch
end
end
end
function handle = boxPlot(frsObj,X,diffIndex,h,dataLabels,varargin)
if(nargin<3)
Expand Down
36 changes: 36 additions & 0 deletions FitResult.m
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,12 @@ function computePlotParams(fitObj,fitNum)
'LineWidth' , 1 );
hx=get(gca,'XLabel'); hy=get(gca,'YLabel');
set([hx hy],'FontName', 'Arial','FontSize',12,'FontWeight','bold');
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(gca);
catch
end
end


end
Expand All @@ -1138,6 +1144,12 @@ function computePlotParams(fitObj,fitNum)
subplot(2,4,4); fitObj.plotSeqCorr;
subplot(2,4,[7 8]); fitObj.plotResidual;
subplot(2,4,[5 6]); fitObj.plotCoeffs;
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(h);
catch
end
end
end
function handle = KSPlot(fitObj,fitNum)
% handle = KSPlot(fitObj)
Expand Down Expand Up @@ -1181,6 +1193,12 @@ function computePlotParams(fitObj,fitNum)
'YTick' , 0:.2:1, ...
'XTick' , 0:.2:1, ...
'LineWidth' , 1 );
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(gca);
catch
end
end
end

function structure = toStructure(fitObj)
Expand Down Expand Up @@ -1279,6 +1297,12 @@ function computePlotParams(fitObj,fitNum)
'YTick' , 0:.25:1, ...
'XTick' , 0:.25:1, ...
'LineWidth' , 1 );
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(gca);
catch
end
end



Expand Down Expand Up @@ -1336,6 +1360,12 @@ function computePlotParams(fitObj,fitNum)
v=axis;
maxY = max(abs(v(3:4)))*(1.1); %add 10%
axis([v(1:2) -maxY maxY]);
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(gca);
catch
end
end
end
function handle = plotResidual(fitObj)
% handle = plotResidual(fitObj)
Expand All @@ -1356,6 +1386,12 @@ function computePlotParams(fitObj,fitNum)
v=axis;
maxY = max(abs(v(3:4)))*(1.1); %add 10%
axis([v(1:2) -maxY maxY]);
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(gca);
catch
end
end
end


Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ nSTAT_Install('RebuildDocSearch', true, 'CleanUserPathPrefs', false)
- `RebuildDocSearch` rebuilds the help search database in `helpfiles/`.
- `CleanUserPathPrefs` removes stale user MATLAB path entries.

Plot style policy:

```matlab
% Modern readability-focused plots (default)
nstat.setPlotStyle('modern');

% Legacy visual style for strict reproduction
nstat.setPlotStyle('legacy');
```

Rendered help documentation (GitHub Pages):
- https://cajigaslab.github.io/nSTAT/

Expand Down
10 changes: 8 additions & 2 deletions SignalObj.m
Original file line number Diff line number Diff line change
Expand Up @@ -2043,8 +2043,14 @@ function clearPlotProps(sObj,index)
h=plot(handle,sObj.time,sObj.data(:,sArray));
end

sObj.setupPlots(handle,sArray);
end
sObj.setupPlots(handle,sArray);
if exist('nstat.applyPlotStyle', 'file') == 2
try
nstat.applyPlotStyle(handle);
catch
end
end
end
function setupPlots(sObj,handle,sArray)
%setupPlots(sObj,sArray)
%Sets the labels for the x-axis, y-axis, and legend.
Expand Down
8 changes: 8 additions & 0 deletions docs/DEVPLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ Policy:
- Always compare **structure** (figure/axes/traces/labels/legend metadata).
- Optional pixel parity for `legacy` style only (determinism-dependent).

## Plot Style Toggle
- Global preference API (PR1):
- `nstat.setPlotStyle('modern')` (default)
- `nstat.setPlotStyle('legacy')`
- `nstat.getPlotStyle`
- Plotting methods call `nstat.applyPlotStyle` and preserve legacy behavior
when style is set to `legacy`.

## Fixture Update Policy
- Fixtures are versioned and treated as protected golden artifacts.
- Update fixtures only when:
Expand Down
158 changes: 158 additions & 0 deletions tools/+nstat/applyPlotStyle.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
function applyPlotStyle(target, varargin)
%APPLYPLOTSTYLE Apply nSTAT plot style to an axes/figure/graphics handle.
%
% Syntax:
% nstat.applyPlotStyle
% nstat.applyPlotStyle(gca)
% nstat.applyPlotStyle(gcf,'Style','legacy')
%
% Name-Value:
% 'Style' - 'legacy' or 'modern'. When omitted, uses nstat.getPlotStyle.

if nargin < 1 || isempty(target)
if isempty(get(groot, 'CurrentFigure'))
return;
end
target = gca;
end

parser = inputParser;
parser.FunctionName = 'nstat.applyPlotStyle';
addParameter(parser, 'Style', '', @(x)ischar(x) || (isstring(x) && isscalar(x)));
parse(parser, varargin{:});

style = char(string(parser.Results.Style));
if isempty(style)
style = nstat.getPlotStyle;
else
style = validateStyle(style);
end

if strcmp(style, 'legacy')
return;
end

[axList, figList] = resolveTargets(target);
if isempty(axList) && isempty(figList)
return;
end

for iFig = 1:numel(figList)
try
set(figList(iFig), 'Color', 'w');
catch
end
end

for iAx = 1:numel(axList)
ax = axList(iAx);
if ~isgraphics(ax, 'axes')
continue;
end

try
set(ax, ...
'FontName', 'Helvetica', ...
'FontSize', 10, ...
'LineWidth', 1, ...
'TickDir', 'out', ...
'Layer', 'top');
catch
end

try
ln = findall(ax, 'Type', 'Line');
for iLine = 1:numel(ln)
lw = get(ln(iLine), 'LineWidth');
if isempty(lw) || ~isnumeric(lw)
continue;
end
if lw < 1.25
set(ln(iLine), 'LineWidth', 1.25);
end
if strcmp(get(ln(iLine), 'Marker'), '.')
set(ln(iLine), 'MarkerSize', max(get(ln(iLine), 'MarkerSize'), 9));
end
end
catch
end

try
sc = findall(ax, 'Type', 'Scatter');
for iSc = 1:numel(sc)
sz = get(sc(iSc), 'SizeData');
if isempty(sz)
continue;
end
set(sc(iSc), 'SizeData', max(sz, 30));
end
catch
end

end

if ~isempty(figList)
try
lgd = findall(figList, 'Type', 'Legend');
for iL = 1:numel(lgd)
if isgraphics(lgd(iL), 'legend')
set(lgd(iL), 'FontSize', 10, 'Box', 'off');
end
end
catch
end
end
end

function [axList, figList] = resolveTargets(target)
axList = gobjects(0);
figList = gobjects(0);

if isgraphics(target)
target = target(:);
else
return;
end

for i = 1:numel(target)
t = target(i);
if isgraphics(t, 'figure')
figList(end+1,1) = t; %#ok<AGROW>
ax = findall(t, 'Type', 'axes');
if ~isempty(ax)
axList = [axList; ax(:)]; %#ok<AGROW>
end
elseif isgraphics(t, 'axes')
axList(end+1,1) = t; %#ok<AGROW>
fig = ancestor(t, 'figure');
if ~isempty(fig)
figList(end+1,1) = fig; %#ok<AGROW>
end
else
ax = ancestor(t, 'axes');
if ~isempty(ax)
axList(end+1,1) = ax; %#ok<AGROW>
fig = ancestor(ax, 'figure');
if ~isempty(fig)
figList(end+1,1) = fig; %#ok<AGROW>
end
end
end
end

if ~isempty(axList)
axList = unique(axList(isgraphics(axList, 'axes')));
end
if ~isempty(figList)
figList = unique(figList(isgraphics(figList, 'figure')));
end
end

function style = validateStyle(style)
style = lower(char(string(style)));
valid = {'legacy', 'modern'};
if ~any(strcmp(style, valid))
error('nstat:plot:InvalidStyle', ...
'Invalid plot style "%s". Valid styles: legacy, modern.', style);
end
end
39 changes: 39 additions & 0 deletions tools/+nstat/getPlotStyle.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
function style = getPlotStyle(varargin)
%GETPLOTSTYLE Get global nSTAT plotting style preference.
%
% Syntax:
% style = nstat.getPlotStyle
% style = nstat.getPlotStyle('Default','legacy')
%
% Name-Value:
% 'Default' - fallback style when no preference is set (default 'modern').
%
% Output:
% style - 'legacy' or 'modern'

parser = inputParser;
parser.FunctionName = 'nstat.getPlotStyle';
addParameter(parser, 'Default', 'modern', @(x)ischar(x) || (isstring(x) && isscalar(x)));
parse(parser, varargin{:});

defaultStyle = validateStyle(parser.Results.Default);
style = defaultStyle;

if ispref('nstat', 'PlotStyle')
try
style = validateStyle(getpref('nstat', 'PlotStyle'));
catch
style = defaultStyle;
end
end
end

function style = validateStyle(style)
style = lower(char(string(style)));
valid = {'legacy', 'modern'};
if ~any(strcmp(style, valid))
error('nstat:plot:InvalidStyle', ...
'Invalid plot style "%s". Valid styles: legacy, modern.', style);
end
end

31 changes: 31 additions & 0 deletions tools/+nstat/setPlotStyle.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
function style = setPlotStyle(style)
%SETPLOTSTYLE Set global nSTAT plotting style preference.
%
% Syntax:
% nstat.setPlotStyle
% nstat.setPlotStyle('legacy')
% style = nstat.setPlotStyle('modern')
%
% Inputs:
% style - 'legacy' or 'modern'. Defaults to 'modern'.
%
% Output:
% style - normalized style value that was saved.

if nargin < 1 || isempty(style)
style = 'modern';
end

style = validateStyle(style);
setpref('nstat', 'PlotStyle', style);
end

function style = validateStyle(style)
style = lower(char(string(style)));
valid = {'legacy', 'modern'};
if ~any(strcmp(style, valid))
error('nstat:plot:InvalidStyle', ...
'Invalid plot style "%s". Valid styles: legacy, modern.', style);
end
end

Loading