2323from Orange .widgets import gui
2424from Orange .widgets .settings import Setting
2525from Orange .widgets .utils import classdensity , colorpalettes
26- from Orange .widgets .utils .plot import OWPalette
2726from Orange .widgets .visualize .utils .customizableplot import Updater , \
2827 CommonParameterSetter
2928from Orange .widgets .visualize .utils .plotutils import (
@@ -534,9 +533,7 @@ def get_size_data(self):
534533 DarkerValue = 120
535534 UnknownColor = (168 , 50 , 168 )
536535
537- COLOR_NOT_SUBSET = (128 , 128 , 128 , 0 )
538- COLOR_SUBSET = (128 , 128 , 128 , 255 )
539- COLOR_DEFAULT = (128 , 128 , 128 , 255 )
536+ COLOR_DEFAULT = (128 , 128 , 128 )
540537
541538 MAX_VISIBLE_LABELS = 500
542539
@@ -1025,7 +1022,7 @@ def get_colors(self):
10251022 else :
10261023 return self ._get_discrete_colors (c_data , subset )
10271024
1028- def _get_same_colors (self , subset ):
1025+ def _get_same_colors (self , subset , color = COLOR_DEFAULT ):
10291026 """
10301027 Return the same pen for all points while the brush color depends
10311028 upon whether the point is in the subset or not
@@ -1038,21 +1035,17 @@ def _get_same_colors(self, subset):
10381035 Returns:
10391036 (tuple): a list of pens and list of brushes
10401037 """
1041- color = self .plot_widget .palette ().color (OWPalette .Data )
1042- pen = [_make_pen (color , 1.5 )] * self .n_shown # use a single QPen instance
1043-
1044- # Prepare all brushes; we use the first two or the last
1045- brushes = []
1046- for c in (self .COLOR_SUBSET , self .COLOR_NOT_SUBSET , self .COLOR_DEFAULT ):
1047- color = QColor (* c )
1048- if color .alpha ():
1049- color .setAlpha (self .alpha_value )
1050- brushes .append (QBrush (color ))
10511038
10521039 if subset is not None :
1053- brush = np .where (subset , * brushes [:2 ])
1040+ colors = [QColor (* color , alpha )
1041+ for alpha in self ._alpha_for_subsets ()]
1042+ brushes = [QBrush (color ) for color in colors ]
1043+ brush = np .where (subset , * brushes )
10541044 else :
1055- brush = brushes [- 1 :] * self .n_shown # use a single QBrush instance
1045+ qcolor = QColor (* color , self .alpha_value )
1046+ brush = np .full (self .n_shown , QBrush (qcolor ))
1047+ qcolor = QColor (* color , self .alpha_value )
1048+ pen = [_make_pen (qcolor , 1.5 )] * self .n_shown
10561049 return pen , brush
10571050
10581051 def _get_continuous_colors (self , c_data , subset ):
@@ -1066,18 +1059,18 @@ def _get_continuous_colors(self, c_data, subset):
10661059
10671060 if np .isnan (c_data ).all ():
10681061 self .palette = palette
1069- return self ._get_continuous_nan_colors ( len ( c_data ) )
1062+ return self ._get_same_colors ( subset , self . palette . nan_color )
10701063
10711064 self .scale = DiscretizedScale (np .nanmin (c_data ), np .nanmax (c_data ))
10721065 bins = self .scale .get_bins ()
10731066 self .palette = \
10741067 colorpalettes .BinnedContinuousPalette .from_palette (palette , bins )
10751068 colors = self .palette .values_to_colors (c_data )
1076- brush = np .hstack (
1077- ( colors ,
1078- np .full (( len ( c_data ), 1 ), self . alpha_value , dtype = np . ubyte )))
1079- pen = ( colors .astype (dtype = float ) * 100 / self .DarkerValue
1080- ). astype ( np . ubyte )
1069+ alphas = np .full (( len ( c_data ), 1 ), self . alpha_value , dtype = np . ubyte )
1070+ brush = np . hstack (( colors , alphas ))
1071+ pen = np .hstack (
1072+ (( colors .astype (dtype = float ) * 100 / self .DarkerValue ). astype ( np . ubyte ),
1073+ alphas ) )
10811074
10821075 # Reuse pens and brushes with the same colors because PyQtGraph then
10831076 # builds smaller pixmap atlas, which makes the drawing faster
@@ -1093,27 +1086,21 @@ def create_pen(col):
10931086 def create_brush (col ):
10941087 return QBrush (QColor (* col ))
10951088
1096- cached_pens = {}
1097- pen = [reuse (cached_pens , create_pen , * col ) for col in pen .tolist ()]
1098-
10991089 if subset is not None :
1090+ alpha_subset , alpha_unset = self ._alpha_for_subsets ()
11001091 brush [:, 3 ] = 0
1101- brush [subset , 3 ] = self .alpha_value
1092+ brush [subset , 3 ] = alpha_subset
1093+ pen [:, 3 ] = alpha_unset
1094+ brush [subset , 3 ] = alpha_subset
11021095
1096+ cached_pens = {}
1097+ pen = [reuse (cached_pens , create_pen , * col ) for col in pen .tolist ()]
11031098 cached_brushes = {}
11041099 brush = np .array ([reuse (cached_brushes , create_brush , * col )
11051100 for col in brush .tolist ()])
11061101
11071102 return pen , brush
11081103
1109- def _get_continuous_nan_colors (self , n ):
1110- nan_color = QColor (* self .palette .nan_color )
1111- nan_pen = _make_pen (nan_color .darker (1.2 ), 1.5 )
1112- pen = np .full (n , nan_pen )
1113- nan_brush = QBrush (nan_color )
1114- brush = np .full (n , nan_brush )
1115- return pen , brush
1116-
11171104 def _get_discrete_colors (self , c_data , subset ):
11181105 """
11191106 Return the pens and colors whose color represent an index into
@@ -1126,20 +1113,44 @@ def _get_discrete_colors(self, c_data, subset):
11261113 c_data [np .isnan (c_data )] = len (self .palette )
11271114 c_data = c_data .astype (int )
11281115 colors = self .palette .qcolors_w_nan
1129- pens = np .array (
1130- [_make_pen (col .darker (self .DarkerValue ), 1.5 ) for col in colors ])
1131- pen = pens [c_data ]
1132- if self .alpha_value < 255 :
1116+ if subset is None :
11331117 for col in colors :
11341118 col .setAlpha (self .alpha_value )
1135- brushes = np .array ([QBrush (col ) for col in colors ])
1136- brush = brushes [c_data ]
1119+ pens = np .array (
1120+ [_make_pen (col .darker (self .DarkerValue ), 1.5 )
1121+ for col in colors ])
1122+ pen = pens [c_data ]
1123+ brushes = np .array ([QBrush (col ) for col in colors ])
1124+ brush = brushes [c_data ]
1125+ else :
1126+ subset_colors = [QColor (col ) for col in colors ]
1127+ alpha_subset , alpha_unset = self ._alpha_for_subsets ()
1128+ for col in subset_colors :
1129+ col .setAlpha (alpha_subset )
1130+ for col in colors :
1131+ col .setAlpha (alpha_unset )
11371132
1138- if subset is not None :
1133+ pens , subset_pens = (
1134+ np .array (
1135+ [_make_pen (col .darker (self .DarkerValue ), 1.5 )
1136+ for col in cols ])
1137+ for cols in (colors , subset_colors ))
1138+ pen = np .where (subset , subset_pens [c_data ], pens [c_data ])
1139+
1140+ brushes = np .array ([QBrush (col ) for col in subset_colors ])
1141+ brush = brushes [c_data ]
11391142 black = np .full (len (brush ), QBrush (QColor (0 , 0 , 0 , 0 )))
11401143 brush = np .where (subset , brush , black )
11411144 return pen , brush
11421145
1146+ def _alpha_for_subsets (self ):
1147+ a , b , c = 1.2 , - 3.2 , 3
1148+ x = self .alpha_value / 255
1149+ alpha_subset = 31 + int (224 * (a * x ** 3 + b * x ** 2 + c * x ))
1150+ x = 1 - x
1151+ alpha_unset = int (255 - 224 * (a * x ** 3 + b * x ** 2 + c * x ))
1152+ return alpha_subset , alpha_unset
1153+
11431154 def update_colors (self ):
11441155 """
11451156 Trigger an update of point colors
0 commit comments