diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 4eff4ec1b5d2..b056d024f6fa 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4163,7 +4163,13 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True, if zorder is None: zorder = mlines.Line2D.zorder - zdelta = 0.1 + # Use 'butt' as the default capstyle to avoid a visual overlap of + # the median line and the boxplot + if medianprops is None or medianprops.get('solid_capstyle', None) is None: + medianprops['solid_capstyle'] = 'butt' + + # put the mean and median line below the box for visual improvement + zdelta = -0.1 def merge_kw_rc(subkey, explicit, zdelta=0, usemarker=True): d = {k.split('.')[-1]: v for k, v in mpl.rcParams.items() diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 30c7e34c937b..17b34fb9d1d6 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -3537,6 +3537,14 @@ def test_boxplot_zorder(): assert ax.boxplot(x)['boxes'][0].get_zorder() == 2 assert ax.boxplot(x, zorder=10)['boxes'][0].get_zorder() == 10 +@check_figures_equal() +def test_boxplot_median_bound_by_box(fig_test, fig_ref): + data = np.arange(3) + medianprops_test = {"linewidth": 12} + medianprops_ref = {**medianprops_test, "solid_capstyle": "butt"} + fig_test.subplots().boxplot(data, medianprops=medianprops_test) + fig_ref.subplots().boxplot(data, medianprops=medianprops_ref) + def test_boxplot_marker_behavior(): plt.rcParams['lines.marker'] = 's'