Repository: scipy/scipy
Pull request: MAINT: stats: probplot: don't plot least-squares fit line unless `fit== True`
#### Reference issue
<!--Example: Closes gh-WXYZ.-->
closes gh-13769

#### What does this implement/fix?
<!--Please explain your changes.-->
`probplot` would draw a least-squares fit line even when `fit==False`.
The fit was always calculated; `fit` only controlled whether the information was returned.
With this change, the least-squares fit line is only calculated and plotted if `fit==True`.

#### Additional information
<!--Any additional information you think is important.-->
The documentation did state for `plot`.

> If given, plots the quantiles and least squares fit.

So this change might be considered a backwards compatibility break and not a bug fix. But I think the original behavior was a bug. I'll let someone else decide.

Alternatively, someone could divine the incantation that would eliminate the least squares fit line from the plot, and we could add that to the documentation.

Problem statement:
probplot draws fit line even when fit=False
The documentation for `probplot` states:
```
    fit : bool, optional
        Fit a least-squares regression (best-fit) line to the sample data if
        True (default).
```

This implies that a best-fit line is only produced if `fit` is True. But in the code, a fit is always calculated and plotted if `plot` is not None, though is only returned if `fit` is True.

This could be resolved by clarifying the documentation (changing "Fit a least-squares..." to "Return a least-squares..."), but I believe it would be better not to draw a line at all if `fit` is False.

If a user wants to compare data to a distribution with specific parameters (e.g., norm(0, 1) rather than just any normal distribution), the least-squares fit line is unhelpful and misleading. Instead the user should plot the 45-degree diagonal and compare the points to that. While the user *could* remove the line from the graph, that requires substantial knowledge of matplotlib., so the user has to create the plot manually.

The current behavior for that combination of options (`plot=ax, fit=False`) has minimal usefulness. It's not that common for a user to want both the plot and the return value, and when they do, it's easy to ignore the second value.

The backwards-incompatibility of changing this would be minimal. It would only cause a problem if someone used these options, which seems rare, and the effect would only be a missing fit line on the plot (rather than a different return value that might cause other code to fail).

#### Reproducing code example:

The best-fit line here is problematic, but there's no easy way to remove it:
```
import matplotlib.pyplot as plt
from scipy import stats

data = stats.norm(0.3, 0.8).rvs(200)
# Do these data come from norm(0, 1)?
fig, ax = plt.subplots()
stats.probplot(data,
               dist=stats.norm(0, 1),
               fit=False,
               plot=ax)
ax.plot([-2, 2], [-2, 2],
        label="norm(0, 1)")
ax.legend()
```

#### Scipy/Numpy/Python version information:
```
1.6.0 1.19.2 sys.version_info(major=3, minor=9, micro=1, releaselevel='final', serial=0)
```

Hints from issue discussion:

Commit message: MAINT: stats: probploy: don't plot least-squares fit line unless `fit == True`

Patch to review:
diff --git a/scipy/stats/morestats.py b/scipy/stats/morestats.py
index 3631887cdcef..d04c79c54d6a 100644
--- a/scipy/stats/morestats.py
+++ b/scipy/stats/morestats.py
@@ -494,7 +494,8 @@ def probplot(x, sparams=(), dist='norm', fit=True, plot=None, rvalue=False):
         Fit a least-squares regression (best-fit) line to the sample data if
         True (default).
     plot : object, optional
-        If given, plots the quantiles and least squares fit.
+        If given, plots the quantiles.
+        If given and `fit` is True, plots the least squares fit.
         `plot` is an object that has to have methods "plot" and "text".
         The `matplotlib.pyplot` module or a Matplotlib Axes object can be used,
         or a custom object with the same methods.
@@ -581,9 +582,8 @@ def probplot(x, sparams=(), dist='norm', fit=True, plot=None, rvalue=False):
 
     """
     x = np.asarray(x)
-    _perform_fit = fit or (plot is not None)
     if x.size == 0:
-        if _perform_fit:
+        if fit:
             return (x, x), (np.nan, np.nan, 0.0)
         else:
             return x, x
@@ -599,12 +599,14 @@ def probplot(x, sparams=(), dist='norm', fit=True, plot=None, rvalue=False):
 
     osm = dist.ppf(osm_uniform, *sparams)
     osr = sort(x)
-    if _perform_fit:
+    if fit:
         # perform a linear least squares fit.
         slope, intercept, r, prob, _ = stats.linregress(osm, osr)
 
     if plot is not None:
-        plot.plot(osm, osr, 'bo', osm, slope*osm + intercept, 'r-')
+        plot.plot(osm, osr, 'bo')
+        if fit:
+            plot.plot(osm, slope*osm + intercept, 'r-')
         _add_axis_labels_title(plot, xlabel='Theoretical quantiles',
                                ylabel='Ordered Values',
                                title='Probability Plot')


Code review comments:
diff_hunk: @@ -494,7 +494,8 @@ def probplot(x, sparams=(), dist='norm', fit=True, plot=None, rvalue=False):
         Fit a least-squares regression (best-fit) line to the sample data if
         True (default).
     plot : object, optional
-        If given, plots the quantiles and least squares fit.
+        If given, plots the quantiles.
+        If given and `fit` is True, plots the least squares fit.
path: scipy/stats/morestats.py
text: @author:
```suggestion
        If given and `fit` is True, also plots the least squares fit.
```