1+ from typing import List
12from xml .sax .saxutils import escape
23
34import numpy as np
@@ -84,8 +85,9 @@ class LinePlotStyle:
8485 SELECTION_LINE_COLOR = QColor (Qt .black )
8586 SELECTION_LINE_WIDTH = 2
8687
88+ UNSELECTED_LINE_WIDTH = 1
8789 UNSELECTED_LINE_ALPHA = 100
88- UNSELECTED_LINE_ALPHA_SEL = 50
90+ UNSELECTED_LINE_ALPHA_SEL = 50 # unselected lines, when selection exists
8991
9092 SELECTED_LINE_WIDTH = 3
9193 SELECTED_LINE_ALPHA = 170
@@ -189,6 +191,11 @@ def reset(self):
189191
190192
191193class ParameterSetter (Setter ):
194+ MEAN_LABEL = "Mean"
195+ LINE_LABEL = "Lines"
196+ SEL_LINE_LABEL = "Selected lines"
197+ RANGE_LABEL = "Range"
198+ SEL_RANGE_LABEL = "Selected range"
192199 initial_settings = {
193200 Setter .LABELS_BOX : {
194201 Setter .FONT_FAMILY_LABEL : Updater .FONT_FAMILY_SETTING ,
@@ -201,9 +208,106 @@ class ParameterSetter(Setter):
201208 Setter .TITLE_LABEL : {Setter .TITLE_LABEL : ("" , "" )},
202209 Setter .X_AXIS_LABEL : {Setter .TITLE_LABEL : ("" , "" )},
203210 Setter .Y_AXIS_LABEL : {Setter .TITLE_LABEL : ("" , "" )},
211+ },
212+ Setter .PLOT_BOX : {
213+ MEAN_LABEL : {
214+ Updater .WIDTH_LABEL : (range (1 , 15 ), LinePlotStyle .MEAN_WIDTH ),
215+ Updater .STYLE_LABEL : (list (Updater .LINE_STYLES ),
216+ Updater .DEFAULT_LINE_STYLE ),
217+ },
218+ LINE_LABEL : {
219+ Updater .WIDTH_LABEL : (range (1 , 15 ),
220+ LinePlotStyle .UNSELECTED_LINE_WIDTH ),
221+ Updater .STYLE_LABEL : (list (Updater .LINE_STYLES ),
222+ Updater .DEFAULT_LINE_STYLE ),
223+ Updater .ALPHA_LABEL : (range (0 , 255 , 5 ),
224+ LinePlotStyle .UNSELECTED_LINE_ALPHA ),
225+ Updater .ANTIALIAS_LABEL : (None , True ),
226+ },
227+ SEL_LINE_LABEL : {
228+ Updater .WIDTH_LABEL : (range (1 , 15 ),
229+ LinePlotStyle .SELECTED_LINE_WIDTH ),
230+ Updater .STYLE_LABEL : (list (Updater .LINE_STYLES ),
231+ Updater .DEFAULT_LINE_STYLE ),
232+ Updater .ALPHA_LABEL : (range (0 , 255 , 5 ),
233+ LinePlotStyle .SELECTED_LINE_ALPHA ),
234+ Updater .ANTIALIAS_LABEL : (None , False ),
235+ },
236+ RANGE_LABEL : {
237+ Updater .ALPHA_LABEL : (range (0 , 255 , 5 ),
238+ LinePlotStyle .RANGE_ALPHA ),
239+ },
240+ SEL_RANGE_LABEL : {
241+ Updater .ALPHA_LABEL : (range (0 , 255 , 5 ),
242+ LinePlotStyle .SELECTED_RANGE_ALPHA ),
243+ },
204244 }
205245 }
206246
247+ def __init__ (self ):
248+ self .mean_settings = {
249+ Updater .WIDTH_LABEL : LinePlotStyle .MEAN_WIDTH ,
250+ Updater .ALPHA_LABEL : 255 ,
251+ Updater .STYLE_LABEL : Updater .DEFAULT_LINE_STYLE ,
252+ Updater .ANTIALIAS_LABEL : True ,
253+ }
254+ self .line_settings = {
255+ Updater .WIDTH_LABEL : LinePlotStyle .UNSELECTED_LINE_WIDTH ,
256+ Updater .ALPHA_LABEL : LinePlotStyle .UNSELECTED_LINE_ALPHA ,
257+ Updater .STYLE_LABEL : Updater .DEFAULT_LINE_STYLE ,
258+ Updater .ANTIALIAS_LABEL : True ,
259+ }
260+ self .sel_line_settings = {
261+ Updater .WIDTH_LABEL : LinePlotStyle .SELECTED_LINE_WIDTH ,
262+ Updater .ALPHA_LABEL : LinePlotStyle .SELECTED_LINE_ALPHA ,
263+ Updater .STYLE_LABEL : Updater .DEFAULT_LINE_STYLE ,
264+ Updater .ANTIALIAS_LABEL : False ,
265+ }
266+ self .range_settings = {
267+ Updater .ALPHA_LABEL : LinePlotStyle .RANGE_ALPHA ,
268+ }
269+ self .sel_range_settings = {
270+ Updater .ALPHA_LABEL : LinePlotStyle .SELECTED_RANGE_ALPHA ,
271+ }
272+ super ().__init__ ()
273+
274+ def update_setters (self ):
275+ def update_mean (** settings ):
276+ self .mean_settings .update (** settings )
277+ Updater .update_lines (self .mean_lines_items , ** self .mean_settings )
278+
279+ def update_lines (** settings ):
280+ self .line_settings .update (** settings )
281+ Updater .update_lines (self .lines_items , ** self .line_settings )
282+
283+ def update_sel_lines (** settings ):
284+ self .sel_line_settings .update (** settings )
285+ Updater .update_lines (self .sel_lines_items , ** self .sel_line_settings )
286+
287+ def _update_brush (items , ** settings ):
288+ for item in items :
289+ brush = item .brush ()
290+ color = brush .color ()
291+ color .setAlpha (settings [Updater .ALPHA_LABEL ])
292+ brush .setColor (color )
293+ item .setBrush (brush )
294+
295+ def update_range (** settings ):
296+ self .range_settings .update (** settings )
297+ _update_brush (self .range_items , ** settings )
298+
299+ def update_sel_range (** settings ):
300+ self .sel_range_settings .update (** settings )
301+ _update_brush (self .sel_range_items , ** settings )
302+
303+ self ._setters [self .PLOT_BOX ] = {
304+ self .MEAN_LABEL : update_mean ,
305+ self .LINE_LABEL : update_lines ,
306+ self .SEL_LINE_LABEL : update_sel_lines ,
307+ self .RANGE_LABEL : update_range ,
308+ self .SEL_RANGE_LABEL : update_sel_range ,
309+ }
310+
207311 @property
208312 def title_item (self ):
209313 return self .getPlotItem ().titleLabel
@@ -216,10 +320,32 @@ def axis_items(self):
216320 def legend_items (self ):
217321 return self .legend .items
218322
323+ @property
324+ def mean_lines_items (self ):
325+ return [group .mean for group in self .groups ]
326+
327+ @property
328+ def lines_items (self ):
329+ return [group .profiles for group in self .groups ]
330+
331+ @property
332+ def sel_lines_items (self ):
333+ return [group .sel_profiles for group in self .groups ] + \
334+ [group .sub_profiles for group in self .groups ]
335+
336+ @property
337+ def range_items (self ):
338+ return [group .range for group in self .groups ]
339+
340+ @property
341+ def sel_range_items (self ):
342+ return [group .sel_range for group in self .groups ]
343+
219344
220345# Customizable plot widget
221346class LinePlotGraph (pg .PlotWidget , ParameterSetter ):
222347 def __init__ (self , parent ):
348+ self .groups : List [ProfileGroup ] = []
223349 self .bottom_axis = BottomAxisItem (orientation = "bottom" )
224350 self .bottom_axis .setLabel ("" )
225351 left_axis = AxisItem (orientation = "left" )
@@ -270,6 +396,7 @@ def reset(self):
270396 self .clear ()
271397 self .getAxis ('bottom' ).set_ticks (None )
272398 self .legend .hide ()
399+ self .groups = []
273400
274401 def select_button_clicked (self ):
275402 self .view_box .set_graph_state (SELECT )
@@ -322,20 +449,19 @@ def __create_curves(self):
322449
323450 def _get_profiles_curve (self ):
324451 x , y , con = self .__get_disconnected_curve_data (self .y_data )
325- color = QColor (self .color )
326- color . setAlpha ( LinePlotStyle . UNSELECTED_LINE_ALPHA )
327- pen = self .make_pen ( color )
328- return pg . PlotCurveItem ( x = x , y = y , connect = con , pen = pen , antialias = True )
452+ pen = self . make_pen (self .color )
453+ curve = pg . PlotCurveItem ( x = x , y = y , connect = con , pen = pen )
454+ Updater . update_lines ([ curve ], ** self .graph . line_settings )
455+ return curve
329456
330457 def _get_sel_profiles_curve (self ):
331- color = QColor (self .color )
332- color .setAlpha (LinePlotStyle .SELECTED_LINE_ALPHA )
333- pen = self .make_pen (color , LinePlotStyle .SELECTED_LINE_WIDTH )
334- return pg .PlotCurveItem (x = None , y = None , pen = pen , antialias = False )
458+ curve = pg .PlotCurveItem (x = None , y = None , pen = self .make_pen (self .color ))
459+ Updater .update_lines ([curve ], ** self .graph .sel_line_settings )
460+ return curve
335461
336462 def _get_range_curve (self ):
337463 color = QColor (self .color )
338- color .setAlpha (LinePlotStyle . RANGE_ALPHA )
464+ color .setAlpha (self . graph . range_settings [ Updater . ALPHA_LABEL ] )
339465 bottom , top = nanmin (self .y_data , axis = 0 ), nanmax (self .y_data , axis = 0 )
340466 return pg .FillBetweenItem (
341467 pg .PlotDataItem (x = self .x_data , y = bottom ),
@@ -344,15 +470,15 @@ def _get_range_curve(self):
344470
345471 def _get_sel_range_curve (self ):
346472 color = QColor (self .color )
347- color .setAlpha (LinePlotStyle . SELECTED_RANGE_ALPHA )
473+ color .setAlpha (self . graph . sel_range_settings [ Updater . ALPHA_LABEL ] )
348474 curve1 = curve2 = pg .PlotDataItem (x = self .x_data , y = self .__mean )
349475 return pg .FillBetweenItem (curve1 , curve2 , brush = color )
350476
351477 def _get_mean_curve (self ):
352- pen = self .make_pen (self .color .darker (LinePlotStyle .MEAN_DARK_FACTOR ),
353- LinePlotStyle . MEAN_WIDTH )
354- return pg . PlotCurveItem ( x = self . x_data , y = self .__mean ,
355- pen = pen , antialias = True )
478+ pen = self .make_pen (self .color .darker (LinePlotStyle .MEAN_DARK_FACTOR ))
479+ curve = pg . PlotCurveItem ( x = self . x_data , y = self . __mean , pen = pen )
480+ Updater . update_lines ([ curve ], ** self .graph . mean_settings )
481+ return curve
356482
357483 def _get_error_bar (self ):
358484 std = nanstd (self .y_data , axis = 0 )
@@ -402,11 +528,12 @@ def set_visible_error(self, show_error=True, **_):
402528
403529 def update_profiles_color (self , selection ):
404530 color = QColor (self .color )
405- alpha = LinePlotStyle . UNSELECTED_LINE_ALPHA if not selection \
406- else LinePlotStyle .UNSELECTED_LINE_ALPHA_SEL
531+ alpha = self . graph . line_settings [ Updater . ALPHA_LABEL ] \
532+ if not selection else LinePlotStyle .UNSELECTED_LINE_ALPHA_SEL
407533 color .setAlpha (alpha )
408- x , y = self .profiles .getData ()
409- self .profiles .setData (x = x , y = y , pen = self .make_pen (color ))
534+ pen = self .profiles .opts ["pen" ]
535+ pen .setColor (color )
536+ self .profiles .setPen (pen )
410537
411538 def update_sel_profiles (self , y_data ):
412539 x , y , connect = self .__get_disconnected_curve_data (y_data ) \
@@ -415,10 +542,10 @@ def update_sel_profiles(self, y_data):
415542
416543 def update_sel_profiles_color (self , subset ):
417544 color = QColor (Qt .black ) if subset else QColor (self .color )
418- color .setAlpha (LinePlotStyle . SELECTED_LINE_ALPHA )
419- pen = self .make_pen ( color , LinePlotStyle . SELECTED_LINE_WIDTH )
420- x , y = self . sel_profiles . getData ( )
421- self .sel_profiles .setData ( x = x , y = y , pen = pen )
545+ color .setAlpha (self . graph . sel_line_settings [ Updater . ALPHA_LABEL ] )
546+ pen = self .sel_profiles . opts [ "pen" ]
547+ pen . setColor ( color )
548+ self .sel_profiles .setPen ( pen )
422549
423550 def update_sub_profiles (self , y_data ):
424551 x , y , connect = self .__get_disconnected_curve_data (y_data ) \
@@ -674,12 +801,14 @@ def plot_groups(self):
674801 group_data = self .data [indices , self .graph_variables ]
675802 self ._plot_group (group_data , indices , index )
676803 self .graph .update_legend (self .group_var )
804+ self .graph .groups = self .__groups
677805 self .graph .view_box .add_profiles (data .X )
678806
679807 def _remove_groups (self ):
680808 for group in self .__groups :
681809 group .remove_items ()
682810 self .graph .view_box .remove_profiles ()
811+ self .graph .groups = []
683812 self .__groups = []
684813
685814 def _plot_group (self , data , indices , index = None ):
0 commit comments