1
1
from .dataui import DataUIManager , full_stack
2
2
from datetime import datetime , timedelta
3
3
import warnings
4
+ from functools import lru_cache
5
+
4
6
5
7
warnings .filterwarnings ("ignore" )
6
8
14
16
import param
15
17
import panel as pn
16
18
import colorcet as cc
19
+ from holoviews .plotting .util import process_cmap
17
20
18
21
pn .extension ("tabulator" , notifications = True , design = "native" )
19
22
#
20
23
LINE_DASH_MAP = ["solid" , "dashed" , "dotted" , "dotdash" , "dashdot" ]
21
24
from vtools .functions .filter import cosine_lanczos
22
25
23
26
27
+ def unique_preserve_order (seq ):
28
+ seen = set ()
29
+ return [x for x in seq if not (x in seen or seen .add (x ))]
30
+
31
+
24
32
def get_color_dataframe (stations , color_cycle = hv .Cycle ()):
25
33
"""
26
34
Create a dataframe with station names and colors
@@ -41,6 +49,15 @@ def get_colors(stations, dfc):
41
49
return hv .Cycle (list (dfc .loc [stations ].values .flatten ()))
42
50
43
51
52
+ @lru_cache
53
+ def get_categorical_color_maps ():
54
+ cmaps = hv .plotting .util .list_cmaps (
55
+ records = True , category = "Categorical" , reverse = False
56
+ )
57
+ cmaps = {c .name + "." + c .provider : c for c in cmaps }
58
+ return cmaps
59
+
60
+
44
61
class TimeSeriesDataUIManager (DataUIManager ):
45
62
time_range = param .CalendarDateRange (
46
63
default = None ,
@@ -74,13 +91,18 @@ class TimeSeriesDataUIManager(DataUIManager):
74
91
default = (0.01 , 0.99 ), bounds = (0 , 1 ), step = 0.01 , doc = "Percentile range"
75
92
)
76
93
file_number_column_name = param .String (default = "FILE_NUM" )
94
+ color_cycle_name = param .Selector (
95
+ objects = list (get_categorical_color_maps ().keys ()),
96
+ default = "glasbey_dark.colorcet" ,
97
+ doc = "Color cycle name" ,
98
+ )
77
99
78
100
def __init__ (
79
101
self , filename_column = "FILE" , file_number_column_name = "FILE_NUM" , ** params
80
102
):
81
- self .color_cycle = hv .Cycle (cc .glasbey_dark )
82
103
# modify catalog if filename_column is present to include file number if multiple files are present
83
104
catalog = self .get_data_catalog ()
105
+ self .change_color_cycle ()
84
106
self .filename_column = filename_column
85
107
self .file_number_column_name = file_number_column_name
86
108
self .display_fileno = False
@@ -135,6 +157,14 @@ def get_name_to_marker(self):
135
157
136
158
return list (MarkerType )
137
159
160
+ @param .depends ("color_cycle_name" , watch = True )
161
+ def change_color_cycle (self ):
162
+ cmapinfo = get_categorical_color_maps ()[self .color_cycle_name ]
163
+ color_list = unique_preserve_order (
164
+ process_cmap (cmapinfo .name , provider = cmapinfo .provider )
165
+ )
166
+ self .color_cycle = hv .Cycle (color_list )
167
+
138
168
def get_widgets (self ):
139
169
control_widgets = pn .Column (
140
170
pn .pane .HTML ("Change time range of data to display:" ),
@@ -158,6 +188,7 @@ def get_widgets(self):
158
188
),
159
189
self .param .irregular_curve_connection ,
160
190
self .param .regular_curve_connection ,
191
+ self .param .color_cycle_name ,
161
192
)
162
193
163
194
return control_widgets
0 commit comments