1- from typing import List , Optional , Union
1+ from typing import List , Literal , Optional , Union
22
33import altair as alt
44import pandas as pd
99from .transforms import create_base_chart
1010
1111
12+ def _determine_highlighted_intersections (
13+ data : pd .DataFrame ,
14+ highlight : Union [Literal ["least" , "greatest" ], int , List [int ]],
15+ ) -> List [float ]:
16+ """Determine which intersection IDs to highlight based on the highlight parameter.
17+
18+ Parameters
19+ ----------
20+ data : pd.DataFrame
21+ The preprocessed data with intersection_id and count columns
22+ highlight : "least", "greatest", int, or list of int
23+ The highlighting criteria
24+
25+ Returns
26+ -------
27+ list of float
28+ List of intersection_ids to highlight
29+ """
30+ # Get unique intersections with their counts
31+ intersections = (
32+ data .groupby ("intersection_id" )["count" ]
33+ .first ()
34+ .reset_index ()
35+ .sort_index ()
36+ )
37+
38+ if isinstance (highlight , str ):
39+ if highlight == "least" :
40+ min_idx = intersections ["count" ].idxmin ()
41+ return [intersections .loc [min_idx , "intersection_id" ]]
42+ else : # highlight == "greatest"
43+ max_idx = intersections ["count" ].idxmax ()
44+ return [intersections .loc [max_idx , "intersection_id" ]]
45+ elif isinstance (highlight , int ):
46+ if highlight < len (intersections ):
47+ return [intersections .iloc [highlight ]["intersection_id" ]]
48+ return []
49+ else : # isinstance(highlight, list)
50+ return [
51+ intersections .iloc [i ]["intersection_id" ]
52+ for i in highlight
53+ if i < len (intersections )
54+ ]
55+
56+
1257class UpSetChart :
1358 """A wrapper class for UpSet plots."""
1459
@@ -84,7 +129,7 @@ def UpSetAltair(
84129 "#BDC6CA" ,
85130 ],
86131 highlight_color : str = "#EA4667" ,
87- highlight : Optional [Union [str , int , List [int ]]] = None ,
132+ highlight : Optional [Union [Literal [ "least" , "greatest" ] , int , List [int ]]] = None ,
88133 glyph_size : int = 100 , # Reduced from 200
89134 set_label_bg_size : int = 500 , # Reduced from 1000
90135 line_connection_size : int = 1 , # Reduced from 2
@@ -230,38 +275,6 @@ def UpSetAltair(
230275 data , sets , abbre , sort_order
231276 )
232277
233- # Determine which intersections to highlight
234- highlighted_intersection_ids = []
235- if highlight is not None :
236- # Get unique intersections with their counts
237- intersections = (
238- data .groupby ("intersection_id" )
239- .agg ({"count" : "first" })
240- .reset_index ()
241- .sort_index ()
242- )
243-
244- if isinstance (highlight , str ):
245- if highlight == "least" :
246- # Find intersection with smallest count
247- min_idx = intersections ["count" ].idxmin ()
248- highlighted_intersection_ids = [intersections .loc [min_idx , "intersection_id" ]]
249- elif highlight == "greatest" :
250- # Find intersection with largest count
251- max_idx = intersections ["count" ].idxmax ()
252- highlighted_intersection_ids = [intersections .loc [max_idx , "intersection_id" ]]
253- elif isinstance (highlight , int ):
254- # Highlight specific index
255- if highlight < len (intersections ):
256- highlighted_intersection_ids = [intersections .iloc [highlight ]["intersection_id" ]]
257- elif isinstance (highlight , list ):
258- # Highlight multiple indices
259- highlighted_intersection_ids = [
260- intersections .iloc [i ]["intersection_id" ]
261- for i in highlight
262- if i < len (intersections )
263- ]
264-
265278 # Setup selections for interactivity
266279 legend_selection = alt .selection_point (fields = ["set" ], bind = "legend" )
267280
@@ -270,10 +283,11 @@ def UpSetAltair(
270283 # Default hover behavior
271284 color_selection = alt .selection_point (fields = ["intersection_id" ], on = "mouseover" )
272285 else :
273- # Fixed highlight based on specified criteria
286+ # Determine which intersections to highlight and create fixed selection
287+ highlighted_ids = _determine_highlighted_intersections (data , highlight )
274288 color_selection = alt .selection_point (
275289 fields = ["intersection_id" ],
276- value = [{"intersection_id" : id_ } for id_ in highlighted_intersection_ids ]
290+ value = [{"intersection_id" : id_ } for id_ in highlighted_ids ]
277291 )
278292
279293 # Calculate dimensions
0 commit comments