minimal examplw
This commit is contained in:
@@ -1,113 +1,151 @@
|
||||
function beautifyBERplot(options)
|
||||
% BEAUTIFYBERPLOT Enhances BER-style plots for publication-quality figures.
|
||||
% Supports automatic smoothing and trend-line overlay.
|
||||
% BEAUTIFYBERPLOT Publication-style beautification for BER / NSD plots.
|
||||
% Style aligned to manual plotting script (lw=0.8, ms=4, white markers).
|
||||
%
|
||||
% Usage examples:
|
||||
% beautifyBERplot; % default
|
||||
% beautifyBERplot("polyfit",1); % add polynomial fit
|
||||
% beautifyBERplot("polyfit",1,"fitmethod","pchip") % piecewise cubic fit
|
||||
%
|
||||
% Supported fitmethod options: 'polyfit', 'smoothingspline', 'loess', 'pchip'
|
||||
% beautifyBERplot
|
||||
% beautifyBERplot("polyfit",true,"polyorder",1)
|
||||
% beautifyBERplot("polyfit",true,"fitmethod","pchip")
|
||||
|
||||
arguments
|
||||
options.logscale (1,1) logical = 1
|
||||
options.setmarkers (1,1) logical = 1;
|
||||
options.polyfit (1,1) logical = 0
|
||||
options.polyorder (1,1) double = 2
|
||||
options.fitmethod (1,1) string = "polyfit" % choose fit type
|
||||
options.logscale (1,1) logical = 1
|
||||
options.setmarkers (1,1) logical = 1
|
||||
options.setcolors (1,1) logical = 1
|
||||
options.polyfit (1,1) logical = 0
|
||||
options.polyorder (1,1) double = 2
|
||||
options.fitmethod (1,1) string = "polyfit"
|
||||
end
|
||||
|
||||
% --- find all line objects in current axes
|
||||
lines = findall(gca, 'Type', 'Line');
|
||||
markers = {'o', 's', 'd', '^', 'v', '>', '<', 'p', 'h'};
|
||||
num_markers = length(markers);
|
||||
ax = gca;
|
||||
|
||||
% --- style all lines consistently
|
||||
for i = 1:length(lines)
|
||||
lines(i).LineWidth = 1.2;
|
||||
% lines(i).LineStyle = '-';
|
||||
if options.setmarkers == 1
|
||||
if string(lines(i).Marker) == "none"
|
||||
lines(i).Marker = markers{mod(i-1, num_markers) + 1};
|
||||
% ---------------------------------------------------------
|
||||
% Extract *only* real data lines from ax.Children
|
||||
% ---------------------------------------------------------
|
||||
children = ax.Children;
|
||||
isLine = arrayfun(@(h) isa(h,'matlab.graphics.chart.primitive.Line'), children);
|
||||
lines = children(isLine);
|
||||
|
||||
% Remove helper lines (e.g. yline, fit overlays)
|
||||
lines = lines(~strcmp({lines.Tag},'ConstantLine'));
|
||||
|
||||
n = numel(lines);
|
||||
if n == 0
|
||||
return
|
||||
end
|
||||
|
||||
% ---------------------------------------------------------
|
||||
% Fixed color palette (deterministic across figures)
|
||||
% ---------------------------------------------------------
|
||||
try
|
||||
cmap = linspecer(n);
|
||||
catch
|
||||
cmap = lines(n).Color; %#ok<NASGU>
|
||||
cmap = linespecer_fallback(n);
|
||||
end
|
||||
|
||||
markers = {'o','s','o','o','^','v','d','>'};
|
||||
lw = 0.8;
|
||||
ms = 4;
|
||||
|
||||
% ---------------------------------------------------------
|
||||
% Apply line + marker styling
|
||||
% ---------------------------------------------------------
|
||||
for i = 1:n
|
||||
ln = lines(n-i+1); % preserve plotting order
|
||||
ln.LineWidth = lw;
|
||||
|
||||
if options.setcolors
|
||||
ln.Color = cmap(i,:);
|
||||
end
|
||||
|
||||
if options.setmarkers
|
||||
if strcmp(ln.Marker,'none')
|
||||
ln.Marker = markers{mod(i-1,numel(markers))+1};
|
||||
end
|
||||
lines(i).MarkerSize = 4;
|
||||
lines(i).MarkerFaceColor = lines(i).Color;
|
||||
ln.MarkerSize = ms;
|
||||
if options.setcolors
|
||||
ln.MarkerEdgeColor = cmap(i,:);
|
||||
end
|
||||
ln.MarkerFaceColor = [1 1 1];
|
||||
end
|
||||
end
|
||||
|
||||
% --- optional smoothing/fitting overlay
|
||||
% ---------------------------------------------------------
|
||||
% Optional smoothing / fitting overlay
|
||||
% ---------------------------------------------------------
|
||||
if options.polyfit
|
||||
hold on
|
||||
for i = 1:length(lines)
|
||||
x = lines(i).XData;
|
||||
y = lines(i).YData;
|
||||
for i = 1:n
|
||||
ln = lines(n-i+1);
|
||||
x = ln.XData(:);
|
||||
y = ln.YData(:);
|
||||
valid = isfinite(x) & isfinite(y);
|
||||
if sum(valid) < options.polyorder + 1
|
||||
continue;
|
||||
|
||||
if sum(valid) < options.polyorder+1
|
||||
continue
|
||||
end
|
||||
|
||||
xf = linspace(min(x(valid)), max(x(valid)), 200);
|
||||
xf = linspace(min(x(valid)),max(x(valid)),200);
|
||||
|
||||
% ----- choose fitting method -----
|
||||
switch lower(options.fitmethod)
|
||||
case "polyfit"
|
||||
p = polyfit(x(valid), y(valid), options.polyorder);
|
||||
yf = polyval(p, xf);
|
||||
p = polyfit(x(valid),y(valid),options.polyorder);
|
||||
yf = polyval(p,xf);
|
||||
|
||||
case "smoothingspline"
|
||||
try
|
||||
f = fit(x(valid)', y(valid)', 'smoothingspline');
|
||||
yf = feval(f, xf);
|
||||
f = fit(x(valid),y(valid),'smoothingspline');
|
||||
yf = feval(f,xf);
|
||||
catch
|
||||
yf = interp1(x(valid), y(valid), xf, 'pchip');
|
||||
yf = interp1(x(valid),y(valid),xf,'pchip');
|
||||
end
|
||||
|
||||
case "loess"
|
||||
yf = smooth(x(valid), y(valid), 0.2, 'loess');
|
||||
yf = interp1(x(valid), yf, xf, 'linear', 'extrap');
|
||||
ys = smooth(x(valid),y(valid),0.2,'loess');
|
||||
yf = interp1(x(valid),ys,xf,'linear','extrap');
|
||||
|
||||
case "pchip"
|
||||
yf = interp1(x(valid), y(valid), xf, 'pchip');
|
||||
yf = interp1(x(valid),y(valid),xf,'pchip');
|
||||
|
||||
otherwise
|
||||
warning('Unknown fitmethod "%s". Using polyfit.', options.fitmethod);
|
||||
p = polyfit(x(valid), y(valid), options.polyorder);
|
||||
yf = polyval(p, xf);
|
||||
p = polyfit(x(valid),y(valid),options.polyorder);
|
||||
yf = polyval(p,xf);
|
||||
end
|
||||
|
||||
% --- lightened color for fit overlay
|
||||
lightcol = lines(i).Color + 0.4 * (1 - lines(i).Color);
|
||||
lightcol(lightcol > 1) = 1;
|
||||
lightcol = ln.Color + 0.4*(1-ln.Color);
|
||||
lightcol(lightcol>1)=1;
|
||||
|
||||
plot(xf, yf, '-', 'Color', lightcol, ...
|
||||
'LineWidth', 0.7, 'Marker', 'none', ...
|
||||
plot(xf,yf,'-','Color',lightcol,...
|
||||
'LineWidth',0.7,'Marker','none',...
|
||||
'HandleVisibility','off');
|
||||
end
|
||||
hold off
|
||||
end
|
||||
|
||||
% --- axis scaling and cosmetics
|
||||
% ---------------------------------------------------------
|
||||
% Axes formatting (matches first script)
|
||||
% ---------------------------------------------------------
|
||||
if options.logscale
|
||||
set(gca, 'YScale', 'log');
|
||||
set(ax,'YScale','log')
|
||||
end
|
||||
|
||||
% --- Figure size in centimeters ---
|
||||
% width_pt = 500;
|
||||
% height_pt = 300;
|
||||
%
|
||||
% pt2cm = 0.03514598; % TeX point → cm
|
||||
% width_cm = width_pt * pt2cm; % = 8.85 cm
|
||||
% height_cm = height_pt * pt2cm; % = 2.81 cm
|
||||
%
|
||||
% set(gcf, 'Units', 'centimeters', 'Position', [2 2 width_cm height_cm]);
|
||||
% set(gcf, 'PaperUnits', 'centimeters', 'PaperPosition', [0 0 width_cm height_cm]);
|
||||
grid(ax,'on')
|
||||
set(ax,'GridLineStyle','--',...
|
||||
'GridLineWidth',0.5,...
|
||||
'MinorGridLineWidth',0.5)
|
||||
|
||||
% --- Formatting ---
|
||||
set(findall(gca, '-property', 'Interpreter'), 'Interpreter', 'latex');
|
||||
set(gcf, 'Color', 'w');
|
||||
set(gca, 'Box', 'on', 'LineWidth', 0.8);
|
||||
grid on;
|
||||
set(gca, 'FontSize', 10, 'FontName', 'Latin Modern Roman');
|
||||
set(ax,'FontSize',12,...
|
||||
'Box','on',...
|
||||
'LineWidth',0.8)
|
||||
|
||||
set(findall(ax,'-property','Interpreter'),'Interpreter','latex')
|
||||
set(gcf,'Color','w')
|
||||
|
||||
end
|
||||
|
||||
% ---------------------------------------------------------
|
||||
% Fallback palette (only used if linspecer is missing)
|
||||
% ---------------------------------------------------------
|
||||
function cmap = linespecer_fallback(n)
|
||||
cmap = lines(n);
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user