1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
from collections import namedtuple
import matplotlib.pyplot as plot
class Style(namedtuple('SS', ['marker', 'line', 'color'])):
def fmt(self):
return self.marker + self.line + self.color
class StyleMap(object):
'''Maps configs (dicts) to specific line styles.'''
DEFAULT = Style(marker='', line= '-', color='k')
ORDER = [ str, bool, float, int ]
def __init__(self, col_list, col_values):
'''Assign (some) columns in @col_list to fields in @Style to vary, and
assign values for these columns to specific field values.'''
self.value_map = {}
self.field_map = {}
# Prioritize non-numbers
def type_priority(column):
value = col_values[column].pop()
col_values[column].add(value)
try:
t = float if float(value) % 1.0 else int
except:
t = bool if value in ['True','False'] else str
return StyleMap.ORDER.index(t)
col_list = sorted(col_list, key=type_priority)
# TODO: undo this, switch to popping mechanism
for field, values in reversed([x for x in self.__get_all()._asdict().iteritems()]):
if not col_list:
break
next_column = col_list.pop(0)
value_dict = {}
for value in sorted(col_values[next_column]):
value_dict[value] = values.pop(0)
self.value_map[next_column] = value_dict
self.field_map[next_column] = field
def __get_all(self):
'''A Style holding all possible values for each property.'''
return Style(marker=list('.,ov^<>1234sp*hH+xDd|_'),
line=['-', ':', '--'],
color=list('bgrcmyk'))
def get_style(self, kv):
'''Translate column values to unique line style.'''
style_fields = {}
for column, values in self.value_map.iteritems():
if column not in kv:
continue
field = self.field_map[column]
style_fields[field] = values[kv[column]]
return StyleMap.DEFAULT._replace(**style_fields)
def get_key(self):
'''A visual description of this StyleMap.'''
key = []
for column, values in self.value_map.iteritems():
for v in values.keys():
sdict = dict([(column, v)])
style = self.get_style(sdict)
styled_line = plot.plot([], [], style.fmt())[0]
description = "%s:%s" % (column, v)
key += [(styled_line, description)]
return sorted(key, key=lambda x:x[1])
|