{"id":7528,"library":"pwlf","title":"pwlf: Piecewise Linear Fitting","description":"pwlf is a Python library (v2.5.2) for fitting continuous piecewise linear functions to 1D data. It allows users to specify the number of line segments and uses global optimization (like differential evolution or L-BFGS-B) to find optimal breakpoint locations. The library also supports fitting with known breakpoints, constrained fits, and provides statistical properties like standard errors and R-squared values. It is actively maintained with regular releases.","status":"active","version":"2.5.2","language":"en","source_language":"en","source_url":"https://github.com/cjekel/piecewise_linear_fit_py","tags":["piecewise linear","regression","curve fitting","optimization","data analysis","mathematics"],"install":[{"cmd":"pip install pwlf","lang":"bash","label":"PyPI"}],"dependencies":[{"reason":"Required for numerical operations and array handling.","package":"numpy","optional":false},{"reason":"Used for optimization algorithms (differential evolution, L-BFGS-B) in fitting routines.","package":"scipy","optional":false}],"imports":[{"note":"The primary class for fitting is 'PiecewiseLinFit' and is typically imported directly from the pwlf package.","wrong":"import pwlf.PiecewiseLinFit","symbol":"PiecewiseLinFit","correct":"from pwlf import PiecewiseLinFit"}],"quickstart":{"code":"import numpy as np\nfrom pwlf import PiecewiseLinFit\n\n# 1. Generate sample data\nx = np.linspace(0, 10, 100)\ny = 2 * x + np.random.normal(0, 0.5, 100) # First segment\ny[50:] = -1 * x[50:] + 20 + np.random.normal(0, 0.5, 50) # Second segment\n\n# 2. Initialize pwlf with your data\nmy_pwlf = PiecewiseLinFit(x, y)\n\n# 3. Fit the function with a specified number of line segments (e.g., 2)\n# The 'fit' method uses global optimization to find the best breakpoint locations.\nbreaks = my_pwlf.fit(2)\nprint(f\"Optimal breakpoints: {breaks}\")\n\n# 4. Predict new y values using the fitted model\nx_new = np.linspace(0, 10, 200)\ny_predicted = my_pwlf.predict(x_new)\n\n# You can also get other statistics after fitting\nr_squared = my_pwlf.r_squared()\nprint(f\"R-squared: {r_squared}\")\n\n# Example of getting slopes (after fit)\nslopes = my_pwlf.slopes\nprint(f\"Slopes of segments: {slopes}\")","lang":"python","description":"This quickstart demonstrates how to use `pwlf` to fit a continuous piecewise linear function. It involves generating sample data, initializing the `PiecewiseLinFit` object, performing a fit for a specified number of line segments, and then predicting values from the fitted model. It also shows how to retrieve the optimal breakpoints and R-squared value."},"warnings":[{"fix":"If reproducibility with older `fitfast` results is critical, you must pin your `pwlf` version to `<2.5.0`. For new work, consider setting a `seed` when initializing `PiecewiseLinFit` for consistent results across runs.","message":"The `fitfast` method's results are no longer reproducible with previous versions (prior to v2.5.0). This is due to the removal of `pyDOE` as a dependency in favor of `scipy`'s own Latin Hypercube Sampling implementation for multi-start optimization.","severity":"breaking","affected_versions":">=2.5.0"},{"fix":"Be aware that statistical outputs like standard errors might have slightly different values compared to `pwlf` versions prior to 2.1.0. Re-evaluate any critical results if upgrading from versions <2.1.0.","message":"In v2.1.0, the internal calculation for least squares changed from `linalg.inv` to `linalg.pinv`. While the API remains the same, this is a 'potentially backwards breaking change' as results, particularly standard error calculations, may differ from those obtained with older versions.","severity":"breaking","affected_versions":">=2.1.0"},{"fix":"Upgrade your Python environment to 3.6 or newer to use current and future versions of `pwlf`. Alternatively, pin `pwlf` to `==2.0.4` if an older Python version is required.","message":"Version 2.0.4 was the last release to officially support Python versions older than 3.6. Users on Python 3.5 or earlier should not upgrade beyond `pwlf==2.0.4`.","severity":"deprecated","affected_versions":">2.0.4"},{"fix":"Always ensure you have substantially more data points than the number of line segments you are trying to fit. Review your data and model complexity.","message":"Fitting a model with more unknowns (e.g., more line segments/breakpoints) than data points can lead to 'perfect' but physically meaningless fits (e.g., zero error, but erratic predictions between data points).","severity":"gotcha","affected_versions":"All versions"},{"fix":"For reproducible results, initialize `pwlf.PiecewiseLinFit` with a `seed` argument, e.g., `my_pwlf = pwlf.PiecewiseLinFit(x, y, seed=123)`.","message":"The `fit` and `fitfast` methods use global optimization which involves stochastic elements (e.g., differential evolution, Latin Hypercube Sampling). Without setting a random seed, results for breakpoint locations can vary slightly between runs.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure `bounds` is a list or tuple of `(lower_bound, upper_bound)` pairs, where the length of the list matches the number of breakpoints (which is `n_segments` for `fit` or `fitfast`). Example: `bounds=[(0.0, 5.0), (5.0, 10.0)]` for 2 segments with 1 breakpoint.","cause":"The `bounds` parameter provided to `fit()` or `fitfast()` is incorrectly formatted or contains non-numeric values. It expects a list of (min, max) tuples for each breakpoint.","error":"ValueError: bounds should be a sequence containing real valued (min, max) pairs for each value in x."},{"fix":"Check your data for sufficient variability and density. Reduce the number of line segments if you have sparse data. Adjust breakpoint bounds to be more flexible, or ensure there are enough data points within each segment.","cause":"This error occurs when the underlying linear algebra problem for the least squares fit is singular or ill-conditioned. Common reasons include having too few data points relative to the number of segments, all data points lying on a single line for multiple segments, or breakpoint bounds being too restrictive.","error":"LinAlgError: This typically means your regression problem is ill-conditioned."},{"fix":"Ensure that one of the `fit` methods is called and executed without errors before attempting to use any post-fitting analysis or prediction methods.","cause":"Methods like `predict()`, `calc_slopes()`, `standard_errors()`, or `r_squared()` are called before a fitting method (`fit()`, `fitfast()`, `fit_with_breaks()`) has successfully completed and established the model parameters.","error":"AttributeError: You have probably not performed a fit yet."},{"fix":"Update `pwlf` to the latest version (>=2.1.0), as this particular warning was addressed by changes in the `calc_slopes` logic during optimization. If the issue persists, review your data and initial breakpoint guesses/bounds to avoid nearly identical or problematic breakpoint locations.","cause":"This warning can occur in older versions of `pwlf` or `numpy` when breakpoints are very close to each other or on the boundary, leading to issues in internal array comparisons during optimization routines for `calc_slopes`.","error":"RuntimeWarning: invalid value encountered in less_equal (or greater)"}]}