Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 71d725f

Browse filesBrowse files
committed
Make Artist.set() apply properties in the order in which they are given.
... with a deprecation period (see changelog). - This is consistent with Artist.update, and we don't reorder separate calls to set_color and set_edgecolor either (we can't really to that, indeed). - The _prop_order mechanism was a slightly complex machinery for a single use case (applying "color" first). - Writing `p.set(edgecolor="r", color="g")` seems a bit twisted anyways. Also rewrote (and simplified) normalize kwargs to make it *also* maintain kwarg order, as that's necessary to make the warning emitted in the correct cases.
1 parent 069fea5 commit 71d725f
Copy full SHA for 71d725f

File tree

Expand file treeCollapse file tree

3 files changed

+47
-45
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+47
-45
lines changed
Open diff view settings
Collapse file

‎doc/api/api_changes_3.3/deprecations.rst‎

Copy file name to clipboardExpand all lines: doc/api/api_changes_3.3/deprecations.rst
+9Lines changed: 9 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,12 @@ The ``cbid`` and ``locator`` attribute are deprecated. Use
545545
~~~~~~~~~~~~~~~~~~~~~~
546546
This function is deprecated in prevision of the future release of PyQt6. The
547547
Qt version can be checked using ``QtCore.QT_VERSION_STR``.
548+
549+
Reordering of parameters by `.Artist.set`
550+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
551+
In a future version, ``Artist.set`` will apply artist properties in the order
552+
in which they are given. This only affects the interaction between the
553+
*color*, *edgecolor*, *facecolor*, and, for `.Collection`\s, *alpha*
554+
properties: the *color* property now needs to be passed first in order not to
555+
override the other properties. This is consistent with e.g. `.Artist.update`,
556+
which did not reorder the properties passed to it.
Collapse file

‎lib/matplotlib/artist.py‎

Copy file name to clipboardExpand all lines: lib/matplotlib/artist.py
+25-8Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ class Artist:
6565
"""
6666

6767
zorder = 0
68-
# order of precedence when bulk setting/updating properties
69-
# via update. The keys should be property names and the values
70-
# integers
71-
_prop_order = dict(color=-1)
7268

7369
def __init__(self):
7470
self._stale = True
@@ -1088,10 +1084,31 @@ def properties(self):
10881084
def set(self, **kwargs):
10891085
"""A property batch setter. Pass *kwargs* to set properties."""
10901086
kwargs = cbook.normalize_kwargs(kwargs, self)
1091-
props = OrderedDict(
1092-
sorted(kwargs.items(), reverse=True,
1093-
key=lambda x: (self._prop_order.get(x[0], 0), x[0])))
1094-
return self.update(props)
1087+
move_color_to_start = False
1088+
if "color" in kwargs:
1089+
keys = [*kwargs]
1090+
i_color = keys.index("color")
1091+
props = ["edgecolor", "facecolor"]
1092+
if any(tp.__module__ == "matplotlib.collections"
1093+
and tp.__name__ == "Collection"
1094+
for tp in type(self).__mro__):
1095+
props.append("alpha")
1096+
for other in props:
1097+
if other not in keys:
1098+
continue
1099+
i_other = keys.index(other)
1100+
if i_other < i_color:
1101+
move_color_to_start = True
1102+
cbook.warn_deprecated(
1103+
"3.3", message=f"You have passed the {other!r} kwarg "
1104+
"before the 'color' kwarg. Artist.set() currently "
1105+
"reorders the properties to apply 'color' first, but "
1106+
"this is deprecated since %(since)s and will be "
1107+
"removed %(removal)s; please pass 'color' first "
1108+
"instead.")
1109+
if move_color_to_start:
1110+
kwargs = {"color": kwargs.pop("color"), **kwargs}
1111+
return self.update(kwargs)
10951112

10961113
def findobj(self, match=None, include_self=True):
10971114
"""
Collapse file

‎lib/matplotlib/cbook/__init__.py‎

Copy file name to clipboardExpand all lines: lib/matplotlib/cbook/__init__.py
+13-37Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,43 +1671,19 @@ def normalize_kwargs(kw, alias_mapping=None, required=(), forbidden=(),
16711671
or isinstance(alias_mapping, Artist)):
16721672
alias_mapping = getattr(alias_mapping, "_alias_map", {})
16731673

1674-
# make a local so we can pop
1675-
kw = dict(kw)
1676-
# output dictionary
1677-
ret = dict()
1678-
1679-
# hit all alias mappings
1680-
for canonical, alias_list in alias_mapping.items():
1681-
1682-
# the alias lists are ordered from lowest to highest priority
1683-
# so we know to use the last value in this list
1684-
tmp = []
1685-
seen = []
1686-
for a in alias_list:
1687-
try:
1688-
tmp.append(kw.pop(a))
1689-
seen.append(a)
1690-
except KeyError:
1691-
pass
1692-
# if canonical is not in the alias_list assume highest priority
1693-
if canonical not in alias_list:
1694-
try:
1695-
tmp.append(kw.pop(canonical))
1696-
seen.append(canonical)
1697-
except KeyError:
1698-
pass
1699-
# if we found anything in this set of aliases put it in the return
1700-
# dict
1701-
if tmp:
1702-
ret[canonical] = tmp[-1]
1703-
if len(tmp) > 1:
1704-
raise TypeError("Got the following keyword arguments which "
1705-
"are aliases of one another: {}"
1706-
.format(", ".join(map(repr, seen))))
1707-
1708-
# at this point we know that all keys which are aliased are removed, update
1709-
# the return dictionary from the cleaned local copy of the input
1710-
ret.update(kw)
1674+
to_canonical = {alias: canonical
1675+
for canonical, alias_list in alias_mapping.items()
1676+
for alias in alias_list}
1677+
canonical_to_seen = {}
1678+
ret = {} # output dictionary
1679+
1680+
for k, v in kw.items():
1681+
canonical = to_canonical.get(k, k)
1682+
if canonical in canonical_to_seen:
1683+
raise TypeError(f"Got both {canonical_to_seen[canonical]!r} and "
1684+
f"{k!r}, which are aliases of one another")
1685+
canonical_to_seen[canonical] = k
1686+
ret[canonical] = v
17111687

17121688
fail_keys = [k for k in required if k not in ret]
17131689
if fail_keys:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.