function beautifyBERplot(options) % BEAUTIFYBERPLOT Publication-style beautification for BER / NSD plots. % Style aligned to manual plotting script (lw=0.8, ms=4, white markers). % % Usage examples: % 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.setcolors (1,1) logical = 1 options.polyfit (1,1) logical = 0 options.polyorder (1,1) double = 2 options.fitmethod (1,1) string = "polyfit" end ax = gca; % --------------------------------------------------------- % 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 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 ln.MarkerSize = ms; if options.setcolors ln.MarkerEdgeColor = cmap(i,:); end ln.MarkerFaceColor = [1 1 1]; end end % --------------------------------------------------------- % Optional smoothing / fitting overlay % --------------------------------------------------------- if options.polyfit hold on 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 end xf = linspace(min(x(valid)),max(x(valid)),200); switch lower(options.fitmethod) case "polyfit" 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); catch yf = interp1(x(valid),y(valid),xf,'pchip'); end case "loess" 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'); otherwise p = polyfit(x(valid),y(valid),options.polyorder); yf = polyval(p,xf); end lightcol = ln.Color + 0.4*(1-ln.Color); lightcol(lightcol>1)=1; plot(xf,yf,'-','Color',lightcol,... 'LineWidth',0.7,'Marker','none',... 'HandleVisibility','off'); end hold off end % --------------------------------------------------------- % Axes formatting (matches first script) % --------------------------------------------------------- if options.logscale set(ax,'YScale','log') end grid(ax,'on') set(ax,'GridLineStyle','--',... 'GridLineWidth',0.5,... 'MinorGridLineWidth',0.5) 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