|
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