4141 Point , TextItem , ViewBox , mkBrush ,
4242 mkPen , setConfigOption , mkColor )
4343from scipy .stats import zscore
44+ from colorspacious import cspace_convert
4445
4546from mne .viz import plot_sensors
4647from mne .viz ._figure import BrowserBase
@@ -125,7 +126,7 @@ def _init_mne_qtapp(enable_icon=True, pg_app=False):
125126 return app
126127
127128
128- def _get_color (color_spec ):
129+ def _get_color (color_spec , invert = False ):
129130 """Wraps mkColor to accept all possible matplotlib color-specifiers."""
130131 try :
131132 # Convert matplotlib color-names if possible
@@ -143,6 +144,12 @@ def _get_color(color_spec):
143144 except ValueError :
144145 raise ValueError (f'"{ color_spec } " is not a valid matplotlib '
145146 f'color-specifier!' ) from None
147+ if invert :
148+ rgba = np .array (color .getRgbF ())
149+ lab = cspace_convert (rgba [:3 ], 'sRGB1' , 'CIELab' )
150+ lab [0 ] = 100. - lab [0 ]
151+ rgba [:3 ] = np .clip (cspace_convert (lab , 'CIELab' , 'sRGB1' ), 0 , 1 )
152+ color .setRgbF (* rgba )
146153
147154 return color
148155
@@ -276,7 +283,7 @@ def update_color(self):
276283 else :
277284 self .color = self .mne .ch_color_ref [self .ch_name ]
278285
279- self .setPen (_get_color (self .color ))
286+ self .setPen (_get_color (self .color , self . mne . dark ))
280287
281288 @propagate_to_children
282289 def update_range_idx (self ):
@@ -560,13 +567,17 @@ def drawPicture(self, p, axisSpec, tickSpecs, textSpecs):
560567 super ().drawPicture (p , axisSpec , tickSpecs , textSpecs )
561568 for rect , flags , text in textSpecs :
562569 if self .mne .butterfly and self .mne .fig_selection is not None :
563- p .setPen (_get_color ('black' ))
570+ p .setPen (_get_color (
571+ 'black' , self .mne .dark ))
564572 elif self .mne .butterfly :
565- p .setPen (_get_color (self .mne .ch_color_dict [text ]))
573+ p .setPen (_get_color (
574+ self .mne .ch_color_dict [text ], self .mne .dark ))
566575 elif text in self .mne .info ['bads' ]:
567- p .setPen (_get_color (self .mne .ch_color_bad ))
576+ p .setPen (_get_color (
577+ self .mne .ch_color_bad , self .mne .dark ))
568578 else :
569- p .setPen (_get_color (self .mne .ch_color_ref [text ]))
579+ p .setPen (_get_color (
580+ self .mne .ch_color_ref [text ], self .mne .dark ))
570581 self .ch_texts [text ] = ((rect .left (), rect .left () + rect .width ()),
571582 (rect .top (), rect .top () + rect .height ()))
572583 p .drawText (rect , int (flags ), text )
@@ -840,7 +851,7 @@ def update_bad_channels(self):
840851 if ch_name in add_chs :
841852 start = self ._mapFromData (0 , line_idx )
842853 stop = self ._mapFromData (self .mne .inst .times [- 1 ], line_idx )
843- pen = _get_color (self .mne .ch_color_bad )
854+ pen = _get_color (self .mne .ch_color_bad , self . mne . dark )
844855 line = self .scene ().addLine (QLineF (start , stop ), pen )
845856 line .setZValue (2 )
846857 self .bad_line_dict [ch_name ] = line
@@ -861,7 +872,7 @@ def update_bad_epochs(self):
861872 start , stop = self .mne .boundary_times [epo_idx :epo_idx + 2 ]
862873 top_left = self ._mapFromData (start , 0 )
863874 bottom_right = self ._mapFromData (stop , len (self .mne .ch_order ))
864- pen = _get_color (self .mne .epoch_color_bad )
875+ pen = _get_color (self .mne .epoch_color_bad , self . mne . dark )
865876 rect = self .scene ().addRect (QRectF (top_left , bottom_right ),
866877 pen = pen , brush = pen )
867878 rect .setZValue (3 )
@@ -876,7 +887,7 @@ def update_events(self):
876887 and self .mne .events_visible :
877888 for ev_t , ev_id in zip (self .mne .event_times , self .mne .event_nums ):
878889 color_name = self .mne .event_color_dict [ev_id ]
879- color = _get_color (color_name )
890+ color = _get_color (color_name , self . mne . dark )
880891 color .setAlpha (100 )
881892 pen = mkPen (color )
882893 top_left = self ._mapFromData (ev_t , 0 )
@@ -909,7 +920,7 @@ def update_annotations(self):
909920 duration = annotations .duration [annot_idx ]
910921 description = annotations .description [annot_idx ]
911922 color_name = self .mne .annotation_segment_colors [description ]
912- color = _get_color (color_name )
923+ color = _get_color (color_name , self . mne . dark )
913924 color .setAlpha (150 )
914925 pen = mkPen (color )
915926 brush = mkBrush (color )
@@ -949,7 +960,7 @@ def update_annotations(self):
949960 color_name = self .mne .annotation_segment_colors [description ]
950961 rect_color = self .annotations_rect_dict [edit_onset ]['color' ]
951962 if color_name != rect_color :
952- color = _get_color (color_name )
963+ color = _get_color (color_name , self . mne . dark )
953964 color .setAlpha (150 )
954965 pen = mkPen (color )
955966 brush = mkBrush (color )
@@ -1137,7 +1148,8 @@ def set_background(self):
11371148 2 , 4 ))
11381149 for line_idx , ch_idx in enumerate (self .mne .ch_order ):
11391150 ch_type = self .mne .ch_types [ch_idx ]
1140- color = _get_color (self .mne .ch_color_dict [ch_type ])
1151+ color = _get_color (
1152+ self .mne .ch_color_dict [ch_type ], self .mne .dark )
11411153 channel_rgba [line_idx , :] = color .getRgb ()
11421154
11431155 channel_rgba = np .require (channel_rgba , np .uint8 , 'C' )
@@ -1964,9 +1976,9 @@ def _region_changed(self):
19641976 def update_color (self ):
19651977 """Update color of annotation-region."""
19661978 color_string = self .mne .annotation_segment_colors [self .description ]
1967- self .base_color = _get_color (color_string )
1968- self .hover_color = _get_color (color_string )
1969- self .text_color = _get_color (color_string )
1979+ self .base_color = _get_color (color_string , self . mne . dark )
1980+ self .hover_color = _get_color (color_string , self . mne . dark )
1981+ self .text_color = _get_color (color_string , self . mne . dark )
19701982 self .base_color .setAlpha (75 )
19711983 self .hover_color .setAlpha (150 )
19721984 self .text_color .setAlpha (255 )
@@ -2151,7 +2163,8 @@ def _init_ui(self):
21512163
21522164 def _add_description_to_cmbx (self , description ):
21532165 color_pixmap = QPixmap (25 , 25 )
2154- color = _get_color (self .mne .annotation_segment_colors [description ])
2166+ color = _get_color (
2167+ self .mne .annotation_segment_colors [description ], self .mne .dark )
21552168 color .setAlpha (75 )
21562169 color_pixmap .fill (color )
21572170 color_icon = QIcon (color_pixmap )
@@ -2367,9 +2380,13 @@ def _set_color(self):
23672380 curr_col = self .mne .annotation_segment_colors [curr_descr ]
23682381 else :
23692382 curr_col = None
2370- color = QColorDialog .getColor (_get_color (curr_col ), self ,
2371- f'Choose color for { curr_descr } !' )
2383+ color = QColorDialog .getColor (
2384+ _get_color (curr_col , self .mne .dark ), self ,
2385+ f'Choose color for { curr_descr } !' )
23722386 if color .isValid ():
2387+ # Invert it (we only want to display inverted colors, all stored
2388+ # colors should be for light mode)
2389+ color = _get_color (color .getRgb (), self .mne .dark )
23732390 self .mne .annotation_segment_colors [curr_descr ] = color
23742391 self ._update_regions_colors ()
23752392 self ._update_description_cmbx ()
@@ -2620,6 +2637,9 @@ def __init__(self, **kwargs):
26202637
26212638 if self .mne .window_title is not None :
26222639 self .setWindowTitle (self .mne .window_title )
2640+ QApplication .processEvents () # needs to happen for the theme to be set
2641+ bgcolor = self .palette ().color (self .backgroundRole ()).getRgbF ()[:3 ]
2642+ self .mne .dark = cspace_convert (bgcolor , 'sRGB1' , 'CIELab' )[0 ] < 50
26232643
26242644 # Initialize attributes which are only used by pyqtgraph, not by
26252645 # matplotlib and add them to MNEBrowseParams.
@@ -2833,7 +2853,7 @@ def __init__(self, **kwargs):
28332853 bgcolor = self .mne .bgcolor
28342854 else :
28352855 bgcolor = 'w'
2836- self .mne .view .setBackground (_get_color (bgcolor ))
2856+ self .mne .view .setBackground (_get_color (bgcolor , self . mne . dark ))
28372857 layout .addWidget (self .mne .view , 0 , 0 )
28382858
28392859 # Initialize Scroll-Bars
0 commit comments