Skip to content

Commit 7bf7e47

Browse files
manit2004timhoffm
andauthored
Add legend.linewidth parameter to control legend box edge linewidth (matplotlib#30780)
* Added legend.linewidth parameter to control legend box edge linewidth * Added legend.linewidth parameter to control legend box edge linewidth * linting issue and mypy subtest issue fixed * suggestions implemented * tests added * suggestion taken and .rst file renamed * Fix linting error --------- Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
1 parent 6cb93cd commit 7bf7e47

File tree

6 files changed

+66
-0
lines changed

6 files changed

+66
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
``legend.linewidth`` rcParam and parameter
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
A new rcParam ``legend.linewidth`` has been added to control the line width of
5+
the legend's box edges. When set to ``None`` (the default), it inherits the
6+
value from ``patch.linewidth``. This allows for independent control of the
7+
legend frame line width without affecting other elements.
8+
9+
The `.Legend` constructor also accepts a new *linewidth* parameter to set the
10+
legend frame line width directly, overriding the rcParam value.
11+
12+
.. plot::
13+
:include-source: true
14+
:alt: A line plot with a legend showing a thick border around the legend box.
15+
16+
import matplotlib.pyplot as plt
17+
18+
fig, ax = plt.subplots()
19+
ax.plot([1, 2, 3], label='data')
20+
ax.legend(linewidth=2.0) # Thick legend box edge
21+
plt.show()

lib/matplotlib/legend.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ def _update_bbox_to_anchor(self, loc_in_canvas):
196196
The legend's background patch edge color.
197197
If ``"inherit"``, use :rc:`axes.edgecolor`.
198198
199+
linewidth : float or None, default: :rc:`legend.linewidth`
200+
The legend's background patch edge linewidth.
201+
If ``None``, use :rc:`patch.linewidth`.
202+
203+
.. versionadded:: 3.11
204+
199205
mode : {"expand", None}
200206
If *mode* is set to ``"expand"`` the legend will be horizontally
201207
expanded to fill the Axes area (or *bbox_to_anchor* if defines
@@ -385,6 +391,7 @@ def __init__(
385391
framealpha=None, # set frame alpha
386392
edgecolor=None, # frame patch edgecolor
387393
facecolor=None, # frame patch facecolor
394+
linewidth=None, # frame patch linewidth
388395

389396
bbox_to_anchor=None, # bbox to which the legend will be anchored
390397
bbox_transform=None, # transform for the bbox
@@ -526,9 +533,12 @@ def __init__(
526533

527534
fancybox = mpl._val_or_rc(fancybox, "legend.fancybox")
528535

536+
linewidth = mpl._val_or_rc(linewidth, "legend.linewidth")
537+
529538
self.legendPatch = FancyBboxPatch(
530539
xy=(0, 0), width=1, height=1,
531540
facecolor=facecolor, edgecolor=edgecolor,
541+
linewidth=linewidth,
532542
# If shadow is used, default to alpha=1 (#8943).
533543
alpha=(framealpha if framealpha is not None
534544
else 1 if shadow

lib/matplotlib/legend.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class Legend(Artist):
8585
framealpha: float | None = ...,
8686
edgecolor: Literal["inherit"] | ColorType | None = ...,
8787
facecolor: Literal["inherit"] | ColorType | None = ...,
88+
linewidth: float | None = ...,
8889
bbox_to_anchor: BboxBase
8990
| tuple[float, float]
9091
| tuple[float, float, float, float]

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@
562562
#legend.framealpha: 0.8 # legend patch transparency
563563
#legend.facecolor: inherit # inherit from axes.facecolor; or color spec
564564
#legend.edgecolor: 0.8 # background patch boundary color
565+
#legend.linewidth: None # line width of the legend frame, None means inherit from patch.linewidth
565566
#legend.fancybox: True # if True, use a rounded box for the
566567
# legend background, else a rectangle
567568
#legend.shadow: False # if True, give background a shadow effect

lib/matplotlib/rcsetup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,8 @@ def _convert_validator_spec(key, conv):
11841184
"legend.frameon": validate_bool,
11851185
# alpha value of the legend frame
11861186
"legend.framealpha": validate_float_or_None,
1187+
# linewidth of legend frame
1188+
"legend.linewidth": validate_float_or_None,
11871189

11881190
## the following dimensions are in fraction of the font size
11891191
"legend.borderpad": validate_float, # units are fontsize

lib/matplotlib/tests/test_legend.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,37 @@ def test_boxplot_legend_labels():
16691669
assert all(x.get_label().startswith("_") for x in bp4['medians'][1:])
16701670

16711671

1672+
def test_legend_linewidth():
1673+
"""Test legend.linewidth parameter and rcParam."""
1674+
fig, ax = plt.subplots()
1675+
ax.plot([1, 2, 3], label='data')
1676+
1677+
# Test direct parameter
1678+
leg = ax.legend(linewidth=2.5)
1679+
assert leg.legendPatch.get_linewidth() == 2.5
1680+
1681+
# Test rcParam
1682+
with mpl.rc_context({'legend.linewidth': 3.0}):
1683+
fig, ax = plt.subplots()
1684+
ax.plot([1, 2, 3], label='data')
1685+
leg = ax.legend()
1686+
assert leg.legendPatch.get_linewidth() == 3.0
1687+
1688+
# Test None default (should inherit from patch.linewidth)
1689+
with mpl.rc_context({'legend.linewidth': None, 'patch.linewidth': 1.5}):
1690+
fig, ax = plt.subplots()
1691+
ax.plot([1, 2, 3], label='data')
1692+
leg = ax.legend()
1693+
assert leg.legendPatch.get_linewidth() == 1.5
1694+
1695+
# Test that direct parameter overrides rcParam
1696+
with mpl.rc_context({'legend.linewidth': 1.0}):
1697+
fig, ax = plt.subplots()
1698+
ax.plot([1, 2, 3], label='data')
1699+
leg = ax.legend(linewidth=4.0)
1700+
assert leg.legendPatch.get_linewidth() == 4.0
1701+
1702+
16721703
def test_patchcollection_legend():
16731704
# Test that PatchCollection labels show up in legend and preserve visual
16741705
# properties (issue #23998)

0 commit comments

Comments
 (0)