Repository: matplotlib/matplotlib

Issue:
[ENH]: Add parameter 'error_linestyle' to plt.errorbar()
### Problem

Currently, **plt.errorbar()** does not provide a direct way to change the linestyle of the error bars themselves. The _linestyle_ parameter only affects the main connecting line, and modifying the error bars requires accessing the returned object and manually setting e.g. _set_linestyle('--')_ on the error bar lines. 

### Proposed solution

Introduce a new parameter, e.g., _error_linestyle_, that allows users to set the linestyle of the error bars directly. Example usage:

`plt.errorbar(x, y, yerr=yerr, fmt='o', error_linestyle='--')`


Discussion:
While naming is debatable, I‘d call this `elinestyle` for consistency with `ecolor` and `elinewidth`.

@MBeusch do you want to make a pull request?
Thanks for the quick response! I originally proposed this as a suggestion rather than something I planned to implement myself. If the idea seems useful, I’d be happy to see it implemented.
Thanks for the feedback. While structurally feasible, I suspect that the need for this functionality is limited. I haven't seen non-solid error bars so far. Therefore, we won't spend time to implement this ourselves. But we will accept a PR if someone has a use case and wants to implement this.



Patch:
diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py
index 3d7899885c59..1b3159a17533 100644
--- a/lib/matplotlib/axes/_axes.py
+++ b/lib/matplotlib/axes/_axes.py
@@ -3463,7 +3463,8 @@ def _errorevery_to_mask(x, errorevery):
     def errorbar(self, x, y, yerr=None, xerr=None,
                  fmt='', ecolor=None, elinewidth=None, capsize=None,
                  barsabove=False, lolims=False, uplims=False,
-                 xlolims=False, xuplims=False, errorevery=1, capthick=None,
+                 xlolims=False, xuplims=False, errorevery=1,
+                 capthick=None, elinestyle=None,
                  **kwargs):
         """
         Plot y versus x as lines and/or markers with attached errorbars.
@@ -3511,6 +3512,12 @@ def errorbar(self, x, y, yerr=None, xerr=None,
             The linewidth of the errorbar lines. If None, the linewidth of
             the current style is used.
 
+        elinestyle : str or tuple, default: 'solid'
+           The linestyle of the errorbar lines.
+           Valid values for linestyles include {'-', '--', '-.',
+            ':', '', (offset, on-off-seq)}. See `.Line2D.set_linestyle` for a
+            complete description.
+
         capsize : float, default: :rc:`errorbar.capsize`
             The length of the error bar caps in points.
 
@@ -3712,6 +3719,9 @@ def _upcast_err(err):
             if key in kwargs:
                 eb_lines_style[key] = kwargs[key]
 
+        if elinestyle is not None:
+            eb_lines_style['linestyle'] = elinestyle
+
         # Make the style dict for caps (the "hats").
         eb_cap_style = {**base_style, 'linestyle': 'none'}
         capsize = mpl._val_or_rc(capsize, "errorbar.capsize")
diff --git a/lib/matplotlib/axes/_axes.pyi b/lib/matplotlib/axes/_axes.pyi
index 7c09376e3d8c..a23a0b27f01b 100644
--- a/lib/matplotlib/axes/_axes.pyi
+++ b/lib/matplotlib/axes/_axes.pyi
@@ -315,6 +315,7 @@ class Axes(_AxesBase):
         *,
         ecolor: ColorType | None = ...,
         elinewidth: float | None = ...,
+        elinestyle: LineStyleType | None = ...,
         capsize: float | None = ...,
         barsabove: bool = ...,
         lolims: bool | ArrayLike = ...,
diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py
index 499fcf750a5e..78fc962d9c5c 100644
--- a/lib/matplotlib/pyplot.py
+++ b/lib/matplotlib/pyplot.py
@@ -3281,6 +3281,7 @@ def errorbar(
     xuplims: bool | ArrayLike = False,
     errorevery: int | tuple[int, int] = 1,
     capthick: float | None = None,
+    elinestyle: LineStyleType | None = None,
     *,
     data=None,
     **kwargs,
@@ -3301,6 +3302,7 @@ def errorbar(
         xuplims=xuplims,
         errorevery=errorevery,
         capthick=capthick,
+        elinestyle=elinestyle,
         **({"data": data} if data is not None else {}),
         **kwargs,
     )


Test patch:
diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py
index 91740bc02dee..f7aea2e6b1b1 100644
--- a/lib/matplotlib/tests/test_axes.py
+++ b/lib/matplotlib/tests/test_axes.py
@@ -4526,6 +4526,14 @@ def test_errorbar_linewidth_type(elinewidth):
     plt.errorbar([1, 2, 3], [1, 2, 3], yerr=[1, 2, 3], elinewidth=elinewidth)
 
 
+def test_errorbar_linestyle_type():
+    eb = plt.errorbar([1, 2, 3], [1, 2, 3],
+                      yerr=[1, 2, 3], elinestyle='--')
+    errorlines = eb[-1][0]
+    errorlinestyle = errorlines.get_linestyle()
+    assert errorlinestyle == [(0, (6, 6))]
+
+
 @check_figures_equal()
 def test_errorbar_nan(fig_test, fig_ref):
     ax = fig_test.add_subplot()