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