|
2 | 2 | unicode_literals)
|
3 | 3 |
|
4 | 4 | from matplotlib.externals import six
|
| 5 | +from collections import OrderedDict |
5 | 6 |
|
6 | 7 | import re
|
7 | 8 | import warnings
|
@@ -82,6 +83,10 @@ class Artist(object):
|
82 | 83 |
|
83 | 84 | aname = 'Artist'
|
84 | 85 | zorder = 0
|
| 86 | + # order of precedence when bulk setting/updating properties |
| 87 | + # via update. The keys should be property names and the values |
| 88 | + # integers |
| 89 | + _prop_order = dict(color=-1) |
85 | 90 |
|
86 | 91 | def __init__(self):
|
87 | 92 | self._stale = True
|
@@ -846,23 +851,43 @@ def update(self, props):
|
846 | 851 | Update the properties of this :class:`Artist` from the
|
847 | 852 | dictionary *prop*.
|
848 | 853 | """
|
849 |
| - store = self.eventson |
850 |
| - self.eventson = False |
851 |
| - changed = False |
852 |
| - |
853 |
| - for k, v in six.iteritems(props): |
854 |
| - if k in ['axes']: |
855 |
| - setattr(self, k, v) |
| 854 | + def _update_property(self, k, v): |
| 855 | + """sorting out how to update property (setter or setattr) |
| 856 | +
|
| 857 | + Parameters |
| 858 | + ---------- |
| 859 | + k : str |
| 860 | + The name of property to update |
| 861 | + v : obj |
| 862 | + The value to assign to the property |
| 863 | + Returns |
| 864 | + ------- |
| 865 | + ret : obj or None |
| 866 | + If using a `set_*` method return it's return, else None. |
| 867 | + """ |
| 868 | + k = k.lower() |
| 869 | + # white list attributes we want to be able to update through |
| 870 | + # art.update, art.set, setp |
| 871 | + if k in {'axes'}: |
| 872 | + return setattr(self, k, v) |
856 | 873 | else:
|
857 | 874 | func = getattr(self, 'set_' + k, None)
|
858 | 875 | if func is None or not six.callable(func):
|
859 | 876 | raise AttributeError('Unknown property %s' % k)
|
860 |
| - func(v) |
861 |
| - changed = True |
862 |
| - self.eventson = store |
863 |
| - if changed: |
| 877 | + return func(v) |
| 878 | + |
| 879 | + store = self.eventson |
| 880 | + self.eventson = False |
| 881 | + try: |
| 882 | + ret = [_update_property(self, k, v) |
| 883 | + for k, v in props.items()] |
| 884 | + finally: |
| 885 | + self.eventson = store |
| 886 | + |
| 887 | + if len(ret): |
864 | 888 | self.pchanged()
|
865 | 889 | self.stale = True
|
| 890 | + return ret |
866 | 891 |
|
867 | 892 | def get_label(self):
|
868 | 893 | """
|
@@ -1015,23 +1040,13 @@ def properties(self):
|
1015 | 1040 | return ArtistInspector(self).properties()
|
1016 | 1041 |
|
1017 | 1042 | def set(self, **kwargs):
|
| 1043 | + """A property batch setter. Pass *kwargs* to set properties. |
1018 | 1044 | """
|
1019 |
| - A property batch setter. Pass *kwargs* to set properties. |
1020 |
| - Will handle property name collisions (e.g., if both |
1021 |
| - 'color' and 'facecolor' are specified, the property |
1022 |
| - with higher priority gets set last). |
| 1045 | + props = OrderedDict( |
| 1046 | + sorted(kwargs.items(), reverse=True, |
| 1047 | + key=lambda x: (self._prop_order.get(x[0], 0), x[0]))) |
1023 | 1048 |
|
1024 |
| - """ |
1025 |
| - ret = [] |
1026 |
| - for k, v in sorted(kwargs.items(), reverse=True): |
1027 |
| - k = k.lower() |
1028 |
| - funcName = "set_%s" % k |
1029 |
| - func = getattr(self, funcName, None) |
1030 |
| - if func is None: |
1031 |
| - raise TypeError('There is no %s property "%s"' % |
1032 |
| - (self.__class__.__name__, k)) |
1033 |
| - ret.extend([func(v)]) |
1034 |
| - return ret |
| 1049 | + return self.update(props) |
1035 | 1050 |
|
1036 | 1051 | def findobj(self, match=None, include_self=True):
|
1037 | 1052 | """
|
@@ -1541,26 +1556,18 @@ def setp(obj, *args, **kwargs):
|
1541 | 1556 | if not cbook.iterable(obj):
|
1542 | 1557 | objs = [obj]
|
1543 | 1558 | else:
|
1544 |
| - objs = cbook.flatten(obj) |
| 1559 | + objs = list(cbook.flatten(obj)) |
1545 | 1560 |
|
1546 | 1561 | if len(args) % 2:
|
1547 | 1562 | raise ValueError('The set args must be string, value pairs')
|
1548 | 1563 |
|
1549 |
| - funcvals = [] |
| 1564 | + # put args into ordereddict to maintain order |
| 1565 | + funcvals = OrderedDict() |
1550 | 1566 | for i in range(0, len(args) - 1, 2):
|
1551 |
| - funcvals.append((args[i], args[i + 1])) |
1552 |
| - funcvals.extend(sorted(kwargs.items(), reverse=True)) |
1553 |
| - |
1554 |
| - ret = [] |
1555 |
| - for o in objs: |
1556 |
| - for s, val in funcvals: |
1557 |
| - s = s.lower() |
1558 |
| - funcName = "set_%s" % s |
1559 |
| - func = getattr(o, funcName, None) |
1560 |
| - if func is None: |
1561 |
| - raise TypeError('There is no %s property "%s"' % |
1562 |
| - (o.__class__.__name__, s)) |
1563 |
| - ret.extend([func(val)]) |
| 1567 | + funcvals[args[i]] = args[i + 1] |
| 1568 | + |
| 1569 | + ret = [o.update(funcvals) for o in objs] |
| 1570 | + ret.extend([o.set(**kwargs) for o in objs]) |
1564 | 1571 | return [x for x in cbook.flatten(ret)]
|
1565 | 1572 |
|
1566 | 1573 |
|
|
0 commit comments