|
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