Skip to content

STY: make default legend edgecolor gray #6770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/api/api_changes/2016-07-20-EF.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
`Legend` initializers gain edgecolor and facecolor kwargs
``````````````````````````````````````````````````````````

The :class:`~matplotlib.legend.Legend` background patch (or 'frame')
can have its `edgecolor` and `facecolor` determined by the
corresponding keyword arguments to its initializer, or to any of the
methods or functions that call that initializer. If left to
their default values of `None`, their values will be taken from
`rcParams`. The previously-existing `framealpha` kwarg still
controls the alpha transparency of the patch.
18 changes: 16 additions & 2 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def legend(self, *args, **kwargs):
label

frameon : None or bool
Control whether a frame should be drawn around the legend.
Control whether the legend should be drawn on a patch (frame).
Default is ``None`` which will take the value from the
``legend.frameon`` :data:`rcParam<matplotlib.rcParams>`.

Expand All @@ -425,10 +425,24 @@ def legend(self, *args, **kwargs):
``legend.shadow`` :data:`rcParam<matplotlib.rcParams>`.

framealpha : None or float
Control the alpha transparency of the legend's frame.
Control the alpha transparency of the legend's background.
Default is ``None`` which will take the value from the
``legend.framealpha`` :data:`rcParam<matplotlib.rcParams>`.

facecolor : None or "inherit" or a color spec
Control the legend's background color.
Default is ``None`` which will take the value from the
``legend.facecolor`` :data:`rcParam<matplotlib.rcParams>`.
If ``"inherit"``, it will take the ``axes.facecolor``
:data:`rcParam<matplotlib.rcParams>`.

edgecolor : None or "inherit" or a color spec
Control the legend's background patch edge color.
Default is ``None`` which will take the value from the
``legend.edgecolor`` :data:`rcParam<matplotlib.rcParams>`.
If ``"inherit"``, it will take the ``axes.edgecolor``
:data:`rcParam<matplotlib.rcParams>`.

mode : {"expand", None}
If `mode` is set to ``"expand"`` the legend will be horizontally
expanded to fill the axes area (or `bbox_to_anchor` if defines
Expand Down
24 changes: 24 additions & 0 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1206,12 +1206,36 @@ def legend(self, handles, labels, *args, **kwargs):
if *False*, legend marker is placed to the right of the legend
label

*frameon*: [ *None* | bool ]
Control whether the legend should be drawn on a patch (frame).
Default is *None* which will take the value from the
``legend.frameon`` :data:`rcParam<matplotlib.rcParams>`.

*fancybox*: [ *None* | *False* | *True* ]
if *True*, draw a frame with a round fancybox. If *None*, use rc

*shadow*: [ *None* | *False* | *True* ]
If *True*, draw a shadow behind legend. If *None*, use rc settings.

*framealpha*: [ *None* | float ]
Control the alpha transparency of the legend's background.
Default is *None* which will take the value from the
``legend.framealpha`` :data:`rcParam<matplotlib.rcParams>`.

*facecolor*: [ *None* | "inherit" | a color spec ]
Control the legend's background color.
Default is *None* which will take the value from the
``legend.facecolor`` :data:`rcParam<matplotlib.rcParams>`.
If ``"inherit"``, it will take the ``axes.facecolor``
:data:`rcParam<matplotlib.rcParams>`.

*edgecolor*: [ *None* | "inherit" | a color spec ]
Control the legend's background patch edge color.
Default is *None* which will take the value from the
``legend.edgecolor`` :data:`rcParam<matplotlib.rcParams>`.
If ``"inherit"``, it will take the ``axes.edgecolor``
:data:`rcParam<matplotlib.rcParams>`.

*ncol* : integer
number of columns. default is 1

Expand Down
31 changes: 16 additions & 15 deletions lib/matplotlib/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ def __init__(self, parent, handles, labels,
title=None, # set a title for the legend

framealpha=None, # set frame alpha
edgecolor=None, # frame patch edgecolor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put these at the end?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? They are all documented as kwargs, not positional arguments, and in the documentation their order differs from their originally random order in the signature.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because they can be passed in as positional.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, they cannot. Axes.legend has no mechanism for doing so. Furthermore, even if there were such a mechanism, it would cause endless confusion because the order in which the kwargs are documented did not correspond to their order in the signature even before my PR.

The real bug in the present PR is that I added the new kwargs to the class docstring but not to the Axes method docstring. I will rectify that now.

facecolor=None, # frame patch facecolor

bbox_to_anchor=None, # bbox that the legend will be anchored.
bbox_transform=None, # transform for the bbox
Expand All @@ -197,21 +199,20 @@ def __init__(self, parent, handles, labels,
================ ====================================================
Keyword Description
================ ====================================================
loc a location code
loc Location code string, or tuple (see below).
prop the font property
fontsize the font size (used only if prop is not specified)
markerscale the relative size of legend markers vs. original
markerfirst If true, place legend marker to left of label
If false, place legend marker to right of label
markerfirst If True (default), marker is to left of the label.
numpoints the number of points in the legend for line
scatterpoints the number of points in the legend for scatter plot
scatteryoffsets a list of yoffsets for scatter symbols in legend
frameon if True, draw a frame around the legend.
If None, use rc
fancybox if True, draw a frame with a round fancybox.
If None, use rc
shadow if True, draw a shadow behind legend
framealpha If not None, alpha channel for the frame.
frameon If True, draw the legend on a patch (frame).
fancybox If True, draw the frame with a round fancybox.
shadow If True, draw a shadow behind legend.
framealpha Transparency of the frame.
edgecolor Frame edgecolor.
facecolor Frame facecolor.
ncol number of columns
borderpad the fractional whitespace inside the legend border
labelspacing the vertical space between the legend entries
Expand Down Expand Up @@ -345,15 +346,15 @@ def __init__(self, parent, handles, labels,
# We use FancyBboxPatch to draw a legend frame. The location
# and size of the box will be updated during the drawing time.

if rcParams["legend.facecolor"] == 'inherit':
facecolor = rcParams["axes.facecolor"]
else:
if facecolor is None:
facecolor = rcParams["legend.facecolor"]
if facecolor == 'inherit':
facecolor = rcParams["axes.facecolor"]

if rcParams["legend.edgecolor"] == 'inherit':
edgecolor = rcParams["axes.edgecolor"]
else:
if edgecolor is None:
edgecolor = rcParams["legend.edgecolor"]
if edgecolor == 'inherit':
edgecolor = rcParams["axes.edgecolor"]

self.legendPatch = FancyBboxPatch(
xy=(0.0, 0.0), width=1., height=1.,
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,7 @@ def validate_hist_bins(s):
'legend.markerscale': [1.0, validate_float],
'legend.shadow': [False, validate_bool],
'legend.facecolor': ['inherit', validate_color_or_inherit],
'legend.edgecolor': ['none', validate_color_or_inherit],
'legend.edgecolor': ['0.8', validate_color_or_inherit],

# tick properties
'xtick.top': [False, validate_bool], # draw ticks on the top side
Expand Down
10 changes: 5 additions & 5 deletions matplotlibrc.template
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,13 @@ backend : $TEMPLATE_BACKEND

### Legend
#legend.loc : best
#legend.frameon : True # whether or not to draw a frame around legend
#legend.framealpha : 0.8 # legend frame transparency
#legend.frameon : True # if True, draw the legend on a background patch
#legend.framealpha : 0.8 # legend patch transparency
#legend.facecolor : inherit # inherit from axes.facecolor; or color spec
#legend.edgecolor : none
#legend.edgecolor : 0.8 # background patch boundary color
#legend.fancybox : True # if True, use a rounded box for the
# legend, else a rectangle
#legend.shadow : False
# legend background, else a rectangle
#legend.shadow : False # if True, give background a shadow effect
#legend.numpoints : 1 # the number of marker points in the legend line
#legend.scatterpoints : 1 # number of scatter points
#legend.markerscale : 1.0 # the relative size of legend markers vs. original
Expand Down