[{"data":1,"prerenderedAt":948},["ShallowReactive",2],{"content-query-uV7xVx6ax0":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"heading":8,"prompt":10,"tags":14,"files":17,"nav":6,"presets":18,"gallery":35,"body":37,"_type":941,"_id":942,"_source":943,"_file":944,"_stem":945,"_extension":946,"sitemap":947},"/tools/savitzky-golay-filter","tools",false,"","Savitzky-Golay Filter Calculator","Apply Savitzky-Golay smoothing online to Excel or CSV data. Preserve peaks, estimate derivatives, and denoise signals with AI.",{"prefix":11,"label":12,"placeholder":13},"Apply a Savitzky-Golay filter","Describe the smoothing or differentiation you want to run","e.g. Savitzky-Golay filter window=21 polyorder=3, compare to moving average, compute first derivative for peak detection",[15,16],"statistics","science",true,[19,25,30],{"label":20,"prompt":21,"dataset_url":22,"dataset_title":23,"dataset_citation":24},"Temperature anomaly smoothing","apply Savitzky-Golay filter (window=11, polyorder=3) to annual global temperature anomaly; compare to SMA(11); overlay both on raw data; show which filter better preserves the rapid warming acceleration after 1980; compute SG first derivative to estimate the rate of warming change over time","https://ourworldindata.org/grapher/temperature-anomaly.csv","Global average temperature anomaly","Our World in Data",{"label":26,"prompt":27,"dataset_url":28,"dataset_title":29,"dataset_citation":24},"CO₂ trend and acceleration","Savitzky-Golay filter (window=21, polyorder=3) on annual CO2 concentration; plot smoothed series; compute and plot first derivative (rate of CO2 increase per year) and second derivative (acceleration); annotate years when CO2 growth rate reached record highs","https://ourworldindata.org/grapher/co2-concentration-long-term.csv","CO₂ concentration in the atmosphere",{"label":31,"prompt":32,"dataset_url":33,"dataset_title":34,"dataset_citation":24},"Energy use smooth + derivative","Savitzky-Golay filter (window=7, polyorder=2) on per-capita energy use; overlay on raw data; compute first derivative to find years of peak growth and peak decline; annotate these inflection points on the original series","https://ourworldindata.org/grapher/per-capita-energy-use.csv","Per capita energy use",[36],"/img/tools/savitzky-golay-filter.png",{"type":38,"children":39,"toc":930},"root",[40,49,77,117,143,149,221,227,366,378,384,518,524,648,654,724,730,775,781,805,836,869],{"type":41,"tag":42,"props":43,"children":45},"element","h2",{"id":44},"what-is-the-savitzky-golay-filter",[46],{"type":47,"value":48},"text","What Is the Savitzky-Golay Filter?",{"type":41,"tag":50,"props":51,"children":52},"p",{},[53,55,61,63,68,70,75],{"type":47,"value":54},"The ",{"type":41,"tag":56,"props":57,"children":58},"strong",{},[59],{"type":47,"value":60},"Savitzky-Golay filter",{"type":47,"value":62}," (SG filter) smooths a noisy signal by fitting a ",{"type":41,"tag":56,"props":64,"children":65},{},[66],{"type":47,"value":67},"local polynomial",{"type":47,"value":69}," to each window of w points using least squares, then evaluating the polynomial at the center point. Unlike the simple moving average, which fits a constant (degree 0 polynomial) to each window, the SG filter fits a polynomial of degree p (typically 2–4), which means it can reproduce curved shapes — peaks, valleys, and inflections — within the window without flattening them. The key result: ",{"type":41,"tag":56,"props":71,"children":72},{},[73],{"type":47,"value":74},"the SG filter preserves the height, width, and position of peaks far better than any equal-width moving average",{"type":47,"value":76},", at the cost of being slightly less aggressive at noise suppression.",{"type":41,"tag":50,"props":78,"children":79},{},[80,82,87,89,94,96,101,103,108,110,115],{"type":47,"value":81},"This property makes the SG filter the standard smoothing algorithm in ",{"type":41,"tag":56,"props":83,"children":84},{},[85],{"type":47,"value":86},"spectroscopy",{"type":47,"value":88},": NMR, Raman, IR, UV-Vis, and mass spectrometry all produce signals with sharp peaks whose precise height and position carry chemical information. A moving average would broaden and shrink these peaks; the SG filter tracks their true shape. Beyond spectroscopy, the SG filter is widely used in ",{"type":41,"tag":56,"props":90,"children":91},{},[92],{"type":47,"value":93},"chromatography",{"type":47,"value":95}," (preserving chromatogram peak areas), ",{"type":41,"tag":56,"props":97,"children":98},{},[99],{"type":47,"value":100},"biomedical signal processing",{"type":47,"value":102}," (ECG, EEG), ",{"type":41,"tag":56,"props":104,"children":105},{},[106],{"type":47,"value":107},"climate science",{"type":47,"value":109}," (smoothing temperature records while preserving rapid warming events), and ",{"type":41,"tag":56,"props":111,"children":112},{},[113],{"type":47,"value":114},"sensor data",{"type":47,"value":116}," (accelerometers, pressure gauges) where fast transients matter.",{"type":41,"tag":50,"props":118,"children":119},{},[120,122,127,129,134,136,141],{"type":47,"value":121},"A second critical capability distinguishes the SG filter from all other smoothers: it can directly compute ",{"type":41,"tag":56,"props":123,"children":124},{},[125],{"type":47,"value":126},"numerical derivatives of a noisy signal",{"type":47,"value":128},". By evaluating the derivative of the fitted local polynomial rather than its value, the filter produces a smoothed first, second, or higher derivative — which would be dominated by noise if computed by finite differences on the raw data. The ",{"type":41,"tag":56,"props":130,"children":131},{},[132],{"type":47,"value":133},"first derivative",{"type":47,"value":135}," is used for peak detection (peaks occur where dy/dx = 0 changes from positive to negative) and for computing rates of change. The ",{"type":41,"tag":56,"props":137,"children":138},{},[139],{"type":47,"value":140},"second derivative",{"type":47,"value":142}," is used for peak sharpening, resolving overlapping peaks, and detecting inflection points in trend data.",{"type":41,"tag":42,"props":144,"children":146},{"id":145},"how-it-works",[147],{"type":47,"value":148},"How It Works",{"type":41,"tag":150,"props":151,"children":152},"ol",{},[153,178,194],{"type":41,"tag":154,"props":155,"children":156},"li",{},[157,162,164,169,171,176],{"type":41,"tag":56,"props":158,"children":159},{},[160],{"type":47,"value":161},"Upload your data",{"type":47,"value":163}," — provide a CSV or Excel file with an ",{"type":41,"tag":56,"props":165,"children":166},{},[167],{"type":47,"value":168},"x",{"type":47,"value":170}," column (wavenumber, time, distance) and a ",{"type":41,"tag":56,"props":172,"children":173},{},[174],{"type":47,"value":175},"y",{"type":47,"value":177}," column (intensity, value, signal). One row per data point.",{"type":41,"tag":154,"props":179,"children":180},{},[181,186,188],{"type":41,"tag":56,"props":182,"children":183},{},[184],{"type":47,"value":185},"Describe the analysis",{"type":47,"value":187}," — e.g. ",{"type":41,"tag":189,"props":190,"children":191},"em",{},[192],{"type":47,"value":193},"\"SG filter window=21 polyorder=3; compare to moving average; compute first derivative; detect peaks from zero-crossings\"",{"type":41,"tag":154,"props":195,"children":196},{},[197,202,204,211,213,219],{"type":41,"tag":56,"props":198,"children":199},{},[200],{"type":47,"value":201},"Get full results",{"type":47,"value":203}," — the AI writes Python code using ",{"type":41,"tag":205,"props":206,"children":208},"a",{"href":207},"https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html",[209],{"type":47,"value":210},"scipy.signal.savgol_filter",{"type":47,"value":212}," and ",{"type":41,"tag":205,"props":214,"children":216},{"href":215},"https://plotly.com/python/",[217],{"type":47,"value":218},"Plotly",{"type":47,"value":220}," to render the smoothed signal, derivative plots, and peak annotations",{"type":41,"tag":42,"props":222,"children":224},{"id":223},"required-data-format",[225],{"type":47,"value":226},"Required Data Format",{"type":41,"tag":228,"props":229,"children":230},"table",{},[231,255],{"type":41,"tag":232,"props":233,"children":234},"thead",{},[235],{"type":41,"tag":236,"props":237,"children":238},"tr",{},[239,245,250],{"type":41,"tag":240,"props":241,"children":242},"th",{},[243],{"type":47,"value":244},"Column",{"type":41,"tag":240,"props":246,"children":247},{},[248],{"type":47,"value":249},"Description",{"type":41,"tag":240,"props":251,"children":252},{},[253],{"type":47,"value":254},"Example",{"type":41,"tag":256,"props":257,"children":258},"tbody",{},[259,325],{"type":41,"tag":236,"props":260,"children":261},{},[262,272,277],{"type":41,"tag":263,"props":264,"children":265},"td",{},[266],{"type":41,"tag":267,"props":268,"children":270},"code",{"className":269},[],[271],{"type":47,"value":168},{"type":41,"tag":263,"props":273,"children":274},{},[275],{"type":47,"value":276},"Independent variable",{"type":41,"tag":263,"props":278,"children":279},{},[280,286,288,294,295,301,303,309,310,316,317,323],{"type":41,"tag":267,"props":281,"children":283},{"className":282},[],[284],{"type":47,"value":285},"400",{"type":47,"value":287},", ",{"type":41,"tag":267,"props":289,"children":291},{"className":290},[],[292],{"type":47,"value":293},"401",{"type":47,"value":287},{"type":41,"tag":267,"props":296,"children":298},{"className":297},[],[299],{"type":47,"value":300},"402",{"type":47,"value":302}," (wavenumber cm⁻¹) or ",{"type":41,"tag":267,"props":304,"children":306},{"className":305},[],[307],{"type":47,"value":308},"1",{"type":47,"value":287},{"type":41,"tag":267,"props":311,"children":313},{"className":312},[],[314],{"type":47,"value":315},"2",{"type":47,"value":287},{"type":41,"tag":267,"props":318,"children":320},{"className":319},[],[321],{"type":47,"value":322},"3",{"type":47,"value":324}," (time)",{"type":41,"tag":236,"props":326,"children":327},{},[328,336,341],{"type":41,"tag":263,"props":329,"children":330},{},[331],{"type":41,"tag":267,"props":332,"children":334},{"className":333},[],[335],{"type":47,"value":175},{"type":41,"tag":263,"props":337,"children":338},{},[339],{"type":47,"value":340},"Signal to smooth",{"type":41,"tag":263,"props":342,"children":343},{},[344,350,351,357,358,364],{"type":41,"tag":267,"props":345,"children":347},{"className":346},[],[348],{"type":47,"value":349},"0.23",{"type":47,"value":287},{"type":41,"tag":267,"props":352,"children":354},{"className":353},[],[355],{"type":47,"value":356},"1.45",{"type":47,"value":287},{"type":41,"tag":267,"props":359,"children":361},{"className":360},[],[362],{"type":47,"value":363},"2.81",{"type":47,"value":365}," (intensity, counts, value)",{"type":41,"tag":50,"props":367,"children":368},{},[369,371,376],{"type":47,"value":370},"Any column names work — describe them in your prompt. Data should be ",{"type":41,"tag":56,"props":372,"children":373},{},[374],{"type":47,"value":375},"regularly spaced",{"type":47,"value":377}," (equal x intervals); if not, ask the AI to resample first.",{"type":41,"tag":42,"props":379,"children":381},{"id":380},"interpreting-the-results",[382],{"type":47,"value":383},"Interpreting the Results",{"type":41,"tag":228,"props":385,"children":386},{},[387,403],{"type":41,"tag":232,"props":388,"children":389},{},[390],{"type":41,"tag":236,"props":391,"children":392},{},[393,398],{"type":41,"tag":240,"props":394,"children":395},{},[396],{"type":47,"value":397},"Output",{"type":41,"tag":240,"props":399,"children":400},{},[401],{"type":47,"value":402},"What it means",{"type":41,"tag":256,"props":404,"children":405},{},[406,422,438,454,470,486,502],{"type":41,"tag":236,"props":407,"children":408},{},[409,417],{"type":41,"tag":263,"props":410,"children":411},{},[412],{"type":41,"tag":56,"props":413,"children":414},{},[415],{"type":47,"value":416},"SG smoothed signal",{"type":41,"tag":263,"props":418,"children":419},{},[420],{"type":47,"value":421},"Polynomial-fitted smooth — preserves peak heights and positions better than moving average",{"type":41,"tag":236,"props":423,"children":424},{},[425,433],{"type":41,"tag":263,"props":426,"children":427},{},[428],{"type":41,"tag":56,"props":429,"children":430},{},[431],{"type":47,"value":432},"First derivative (dy/dx)",{"type":41,"tag":263,"props":434,"children":435},{},[436],{"type":47,"value":437},"Rate of change — zero-crossings from + to − = signal peaks; from − to + = troughs",{"type":41,"tag":236,"props":439,"children":440},{},[441,449],{"type":41,"tag":263,"props":442,"children":443},{},[444],{"type":41,"tag":56,"props":445,"children":446},{},[447],{"type":47,"value":448},"Second derivative (d²y/dx²)",{"type":41,"tag":263,"props":450,"children":451},{},[452],{"type":47,"value":453},"Curvature — negative at peaks, useful for resolving overlapping bands",{"type":41,"tag":236,"props":455,"children":456},{},[457,465],{"type":41,"tag":263,"props":458,"children":459},{},[460],{"type":41,"tag":56,"props":461,"children":462},{},[463],{"type":47,"value":464},"Window size w",{"type":41,"tag":263,"props":466,"children":467},{},[468],{"type":47,"value":469},"Must be odd; larger = smoother but more peak broadening; typical range 5–51",{"type":41,"tag":236,"props":471,"children":472},{},[473,481],{"type":41,"tag":263,"props":474,"children":475},{},[476],{"type":41,"tag":56,"props":477,"children":478},{},[479],{"type":47,"value":480},"Polynomial order p",{"type":41,"tag":263,"props":482,"children":483},{},[484],{"type":47,"value":485},"Must be \u003C w; higher order = better peak preservation; typical p = 2 or 3",{"type":41,"tag":236,"props":487,"children":488},{},[489,497],{"type":41,"tag":263,"props":490,"children":491},{},[492],{"type":41,"tag":56,"props":493,"children":494},{},[495],{"type":47,"value":496},"Comparison to SMA",{"type":41,"tag":263,"props":498,"children":499},{},[500],{"type":47,"value":501},"SG better preserves peak heights; SMA produces lower overall noise — tradeoff",{"type":41,"tag":236,"props":503,"children":504},{},[505,513],{"type":41,"tag":263,"props":506,"children":507},{},[508],{"type":41,"tag":56,"props":509,"children":510},{},[511],{"type":47,"value":512},"Residuals (raw − SG)",{"type":41,"tag":263,"props":514,"children":515},{},[516],{"type":47,"value":517},"Should be random noise; systematic structure = p too low for the signal shape",{"type":41,"tag":42,"props":519,"children":521},{"id":520},"example-prompts",[522],{"type":47,"value":523},"Example Prompts",{"type":41,"tag":228,"props":525,"children":526},{},[527,543],{"type":41,"tag":232,"props":528,"children":529},{},[530],{"type":41,"tag":236,"props":531,"children":532},{},[533,538],{"type":41,"tag":240,"props":534,"children":535},{},[536],{"type":47,"value":537},"Scenario",{"type":41,"tag":240,"props":539,"children":540},{},[541],{"type":47,"value":542},"What to type",{"type":41,"tag":256,"props":544,"children":545},{},[546,563,580,597,614,631],{"type":41,"tag":236,"props":547,"children":548},{},[549,554],{"type":41,"tag":263,"props":550,"children":551},{},[552],{"type":47,"value":553},"Basic smoothing",{"type":41,"tag":263,"props":555,"children":556},{},[557],{"type":41,"tag":267,"props":558,"children":560},{"className":559},[],[561],{"type":47,"value":562},"SG filter window=21 polyorder=3 on spectral data; overlay on raw; compare to SMA(21)",{"type":41,"tag":236,"props":564,"children":565},{},[566,571],{"type":41,"tag":263,"props":567,"children":568},{},[569],{"type":47,"value":570},"Peak detection",{"type":41,"tag":263,"props":572,"children":573},{},[574],{"type":41,"tag":267,"props":575,"children":577},{"className":576},[],[578],{"type":47,"value":579},"SG smooth then first derivative; find peaks where derivative changes sign from + to −; report peak positions and heights",{"type":41,"tag":236,"props":581,"children":582},{},[583,588],{"type":41,"tag":263,"props":584,"children":585},{},[586],{"type":47,"value":587},"Derivative plot",{"type":41,"tag":263,"props":589,"children":590},{},[591],{"type":41,"tag":267,"props":592,"children":594},{"className":593},[],[595],{"type":47,"value":596},"compute and plot first and second derivatives of the signal using SG window=25 polyorder=4",{"type":41,"tag":236,"props":598,"children":599},{},[600,605],{"type":41,"tag":263,"props":601,"children":602},{},[603],{"type":47,"value":604},"Window comparison",{"type":41,"tag":263,"props":606,"children":607},{},[608],{"type":41,"tag":267,"props":609,"children":611},{"className":610},[],[612],{"type":47,"value":613},"apply SG with windows 11, 21, and 41 (all polyorder=3); overlay; which window preserves the smallest peaks?",{"type":41,"tag":236,"props":615,"children":616},{},[617,622],{"type":41,"tag":263,"props":618,"children":619},{},[620],{"type":47,"value":621},"Overlapping peaks",{"type":41,"tag":263,"props":623,"children":624},{},[625],{"type":41,"tag":267,"props":626,"children":628},{"className":627},[],[629],{"type":47,"value":630},"second derivative plot to resolve overlapping peaks; annotate each minimum (= peak center in 2nd deriv)",{"type":41,"tag":236,"props":632,"children":633},{},[634,639],{"type":41,"tag":263,"props":635,"children":636},{},[637],{"type":47,"value":638},"Chromatogram",{"type":41,"tag":263,"props":640,"children":641},{},[642],{"type":41,"tag":267,"props":643,"children":645},{"className":644},[],[646],{"type":47,"value":647},"SG filter (window=15, polyorder=2) on chromatogram; detect peaks from first derivative zero-crossings; report retention times and peak areas",{"type":41,"tag":42,"props":649,"children":651},{"id":650},"assumptions-to-check",[652],{"type":47,"value":653},"Assumptions to Check",{"type":41,"tag":655,"props":656,"children":657},"ul",{},[658,676,686,696,706],{"type":41,"tag":154,"props":659,"children":660},{},[661,666,668,674],{"type":41,"tag":56,"props":662,"children":663},{},[664],{"type":47,"value":665},"Regular spacing",{"type":47,"value":667}," — ",{"type":41,"tag":267,"props":669,"children":671},{"className":670},[],[672],{"type":47,"value":673},"savgol_filter",{"type":47,"value":675}," requires evenly spaced x values; if your data has gaps or irregular spacing, resample to a uniform grid first",{"type":41,"tag":154,"props":677,"children":678},{},[679,684],{"type":41,"tag":56,"props":680,"children":681},{},[682],{"type":47,"value":683},"Window size odd and > polyorder",{"type":47,"value":685}," — the window must be odd (so there is a well-defined center) and strictly greater than the polynomial order: w > p",{"type":41,"tag":154,"props":687,"children":688},{},[689,694],{"type":41,"tag":56,"props":690,"children":691},{},[692],{"type":47,"value":693},"Window \u003C\u003C signal features",{"type":47,"value":695}," — the window should be smaller than the narrowest feature you want to preserve; a window wider than a peak will smooth it away even with high polynomial order",{"type":41,"tag":154,"props":697,"children":698},{},[699,704],{"type":41,"tag":56,"props":700,"children":701},{},[702],{"type":47,"value":703},"Polyorder 2 or 3 for most applications",{"type":47,"value":705}," — p = 2 or 3 is the standard choice; higher orders (4–5) can overfit to noise at the window edges",{"type":41,"tag":154,"props":707,"children":708},{},[709,714,716,722],{"type":41,"tag":56,"props":710,"children":711},{},[712],{"type":47,"value":713},"Edge effects",{"type":47,"value":715}," — the first and last (w−1)/2 points use reflected or truncated windows (depending on ",{"type":41,"tag":267,"props":717,"children":719},{"className":718},[],[720],{"type":47,"value":721},"mode",{"type":47,"value":723},") and may show artifacts; inspect the edges of your filtered output",{"type":41,"tag":42,"props":725,"children":727},{"id":726},"related-tools",[728],{"type":47,"value":729},"Related Tools",{"type":41,"tag":50,"props":731,"children":732},{},[733,735,741,743,749,751,757,759,765,767,773],{"type":47,"value":734},"Use the ",{"type":41,"tag":205,"props":736,"children":738},{"href":737},"/tools/moving-average",[739],{"type":47,"value":740},"Moving Average Calculator",{"type":47,"value":742}," when you need a simpler, computationally cheaper smoother and peak preservation is not critical. Use the ",{"type":41,"tag":205,"props":744,"children":746},{"href":745},"/tools/moving-median-filter",[747],{"type":47,"value":748},"Moving Median Filter",{"type":47,"value":750}," when your data contains isolated spike outliers (the SG filter is not robust to outliers — a single spike distorts the local polynomial fit). Use the ",{"type":41,"tag":205,"props":752,"children":754},{"href":753},"/tools/gaussian-peak-fit",[755],{"type":47,"value":756},"Gaussian Peak Fit",{"type":47,"value":758}," or ",{"type":41,"tag":205,"props":760,"children":762},{"href":761},"/tools/lorentzian-peak-fit",[763],{"type":47,"value":764},"Lorentzian Peak Fit",{"type":47,"value":766}," to fit explicit parametric peak models to the smoothed spectrum after SG filtering. Use the ",{"type":41,"tag":205,"props":768,"children":770},{"href":769},"/tools/time-series-decomposition",[771],{"type":47,"value":772},"Time Series Decomposition",{"type":47,"value":774}," tool for time series with trend and seasonality rather than a spectral signal with peaks.",{"type":41,"tag":42,"props":776,"children":778},{"id":777},"frequently-asked-questions",[779],{"type":47,"value":780},"Frequently Asked Questions",{"type":41,"tag":50,"props":782,"children":783},{},[784,789,791,796,798,803],{"type":41,"tag":56,"props":785,"children":786},{},[787],{"type":47,"value":788},"When should I use Savitzky-Golay instead of a moving average?",{"type":47,"value":790},"\nUse the ",{"type":41,"tag":56,"props":792,"children":793},{},[794],{"type":47,"value":795},"SG filter",{"type":47,"value":797}," whenever the shape of features in your signal matters — peak heights, widths, and positions; rates of change (via derivatives); inflection points. The SG filter preserves these at the cost of slightly more residual noise. Use the ",{"type":41,"tag":56,"props":799,"children":800},{},[801],{"type":47,"value":802},"moving average",{"type":47,"value":804}," when you only care about the overall trend and have no narrow peaks to preserve, or when simplicity matters (SMA is trivial to reproduce in any spreadsheet). A practical test: apply both and check whether the peaks in the SG output are taller and narrower than in the SMA output — they should be.",{"type":41,"tag":50,"props":806,"children":807},{},[808,813,815,820,822,827,829,834],{"type":41,"tag":56,"props":809,"children":810},{},[811],{"type":47,"value":812},"How do I choose window size and polynomial order?",{"type":47,"value":814},"\nThe ",{"type":41,"tag":56,"props":816,"children":817},{},[818],{"type":47,"value":819},"window size",{"type":47,"value":821}," w should be approximately 3–5× the FWHM (full width at half maximum) of the narrowest feature you want to smooth ",{"type":41,"tag":189,"props":823,"children":824},{},[825],{"type":47,"value":826},"without",{"type":47,"value":828}," distorting. A window much larger than the feature width will broaden and reduce peak height; a window smaller than the feature width provides little smoothing benefit. Start with w = FWHM × 4 and adjust. The ",{"type":41,"tag":56,"props":830,"children":831},{},[832],{"type":47,"value":833},"polynomial order",{"type":47,"value":835}," p = 2 catches parabolic shapes (most peaks); p = 3 adds an asymmetry term and is the most common choice for spectroscopy; p = 4 or 5 is rarely needed and can overfit noise at the window edges.",{"type":41,"tag":50,"props":837,"children":838},{},[839,844,846,852,854,860,862,867],{"type":41,"tag":56,"props":840,"children":841},{},[842],{"type":47,"value":843},"Can the SG filter compute numerical derivatives?",{"type":47,"value":845},"\nYes — this is one of its major advantages. ",{"type":41,"tag":267,"props":847,"children":849},{"className":848},[],[850],{"type":47,"value":851},"scipy.signal.savgol_filter(y, window, polyorder, deriv=1)",{"type":47,"value":853}," returns the first derivative dy/dx evaluated by differentiating the locally fitted polynomial, which is far less noisy than finite differences on the raw signal. The second derivative (",{"type":41,"tag":267,"props":855,"children":857},{"className":856},[],[858],{"type":47,"value":859},"deriv=2",{"type":47,"value":861},") is used in spectroscopy to resolve overlapping peaks: each peak in the original signal appears as a negative minimum in the second derivative, and overlapping peaks that appear as shoulders become distinct minima. Ask the AI to ",{"type":41,"tag":189,"props":863,"children":864},{},[865],{"type":47,"value":866},"\"compute the second derivative with SG window=21 polyorder=4; find minima to resolve overlapping peaks\"",{"type":47,"value":868},".",{"type":41,"tag":50,"props":870,"children":871},{},[872,877,879,884,886,892,893,899,900,906,907,913,915,920,922,928],{"type":41,"tag":56,"props":873,"children":874},{},[875],{"type":47,"value":876},"My filtered signal has artifacts at the edges — what's wrong?",{"type":47,"value":878},"\nEdge effects are inherent to any sliding-window filter. At the first and last (w−1)/2 points, there are not enough data points on one side to fill the window, so ",{"type":41,"tag":267,"props":880,"children":882},{"className":881},[],[883],{"type":47,"value":673},{"type":47,"value":885}," uses one of several boundary modes (",{"type":41,"tag":267,"props":887,"children":889},{"className":888},[],[890],{"type":47,"value":891},"mirror",{"type":47,"value":287},{"type":41,"tag":267,"props":894,"children":896},{"className":895},[],[897],{"type":47,"value":898},"nearest",{"type":47,"value":287},{"type":41,"tag":267,"props":901,"children":903},{"className":902},[],[904],{"type":47,"value":905},"wrap",{"type":47,"value":287},{"type":41,"tag":267,"props":908,"children":910},{"className":909},[],[911],{"type":47,"value":912},"constant",{"type":47,"value":914},"). The ",{"type":41,"tag":267,"props":916,"children":918},{"className":917},[],[919],{"type":47,"value":891},{"type":47,"value":921}," mode (default) reflects the signal at the boundary — adequate for most cases but can introduce spurious oscillations if the signal changes sharply near the edge. Solutions: (1) trim the first and last (w−1)/2 points from the output before plotting; (2) use ",{"type":41,"tag":267,"props":923,"children":925},{"className":924},[],[926],{"type":47,"value":927},"mode='nearest'",{"type":47,"value":929}," which pads with the endpoint value; (3) extend your data with a few padding points before filtering and remove them afterward.",{"title":7,"searchDepth":931,"depth":931,"links":932},2,[933,934,935,936,937,938,939,940],{"id":44,"depth":931,"text":48},{"id":145,"depth":931,"text":148},{"id":223,"depth":931,"text":226},{"id":380,"depth":931,"text":383},{"id":520,"depth":931,"text":523},{"id":650,"depth":931,"text":653},{"id":726,"depth":931,"text":729},{"id":777,"depth":931,"text":780},"markdown","content:tools:057.savitzky-golay-filter.md","content","tools/057.savitzky-golay-filter.md","tools/057.savitzky-golay-filter","md",{"loc":4},1775502471864]