@@ -18,6 +18,71 @@ def str2bool(v):
1818 return v .lower () in ("yes" , "true" , "t" , "1" )
1919
2020
21+ def test_groups (fig , df_grouped ):
22+ """Test if plotly figure curve names match up with pandas dataframe groups
23+
24+ Args:
25+ fig (plotly figure): _description_
26+ groups (pandas groupby object): _description_
27+
28+ Returns:
29+ _type_: Bool describing whether or not groups is the correct dataframe grouping descbrining the data in fig
30+ """
31+ str_groups = {}
32+ for name , group in df_grouped :
33+ # if isinstance(name, bool) or isinstance(name, int):
34+ # str_groups[str(name)] = group
35+ if isinstance (name , tuple ):
36+ str_groups [", " .join (str (x ) for x in name )] = group
37+ else :
38+ str_groups [name ] = group
39+
40+ for data in fig .data :
41+ if data .name in str_groups :
42+ if len (data .y ) == len (str_groups [data .name ]):
43+ continue
44+ else :
45+ return False
46+ return True
47+
48+
49+ def find_grouping (fig , df_data , cols ):
50+
51+ if len (cols ) == 1 :
52+ df_grouped = df_data .groupby (cols )
53+ if not test_groups (fig , df_grouped ):
54+ raise ValueError (
55+ "marker_col is mispecified because the dataframe grouping names don't match the names in the plotly figure."
56+ )
57+
58+ elif len (cols ) == 2 : # color_col and marker_col
59+
60+ df_grouped_x = df_data .groupby (cols )
61+ df_grouped_y = df_data .groupby ([cols [1 ], cols [0 ]])
62+
63+ if test_groups (fig , df_grouped_x ):
64+ df_grouped = df_grouped_x
65+
66+ elif test_groups (fig , df_grouped_y ):
67+ df_grouped = df_grouped_y
68+ else :
69+ raise ValueError (
70+ "color_col and marker_col are mispecified because their dataframe grouping names don't match the names in the plotly figure."
71+ )
72+ else :
73+ raise ValueError ("Too many columns specified for grouping." )
74+
75+ str_groups = {}
76+ for name , group in df_grouped :
77+ if isinstance (name , tuple ):
78+ str_groups [", " .join (str (x ) for x in name )] = group
79+ else :
80+ str_groups [name ] = group
81+
82+ curve_dict = {index : str_groups [x ["name" ]] for index , x in enumerate (fig .data )}
83+ return df_grouped , curve_dict
84+
85+
2186def add_molecules (
2287 fig ,
2388 df ,
@@ -31,6 +96,7 @@ def add_molecules(
3196 caption_cols = None ,
3297 caption_transform = {},
3398 color_col = None ,
99+ marker_col = None ,
34100 wrap = True ,
35101 wraplen = 20 ,
36102 width = 150 ,
@@ -77,22 +143,25 @@ def add_molecules(
77143 the font size used in the hover box - the font of the title line is fontsize+2 (default 12)
78144 """
79145 fig .update_traces (hoverinfo = "none" , hovertemplate = None )
80-
146+ df_data = df .copy ()
147+ if color_col is not None :
148+ df_data [color_col ] = df_data [color_col ].astype (str )
149+ if marker_col is not None :
150+ df_data [marker_col ] = df_data [marker_col ].astype (str )
81151 colors = {0 : "black" }
152+
82153 if len (fig .data ) != 1 :
83- if color_col is not None :
84- colors = {index : x .marker ["color" ] for index , x in enumerate (fig .data )}
85- if df [color_col ].dtype == bool :
86- curve_dict = {
87- index : str2bool (x ["name" ]) for index , x in enumerate (fig .data )
88- }
89- elif df [color_col ].dtype == int :
90- curve_dict = {index : int (x ["name" ]) for index , x in enumerate (fig .data )}
91- else :
92- curve_dict = {index : x ["name" ] for index , x in enumerate (fig .data )}
93- else :
154+ if color_col is None and marker_col is None :
94155 raise ValueError (
95- "color_col needs to be specified if there is more than one plotly curve in the figure!"
156+ "More than one plotly curve in figure - color_col and/or marker_col needs to be specified."
157+ )
158+ if color_col is None :
159+ df_grouped , curve_dict = find_grouping (fig , df_data , [marker_col ])
160+ elif marker_col is None :
161+ df_grouped , curve_dict = find_grouping (fig , df_data , [color_col ])
162+ else :
163+ df_grouped , curve_dict = find_grouping (
164+ fig , df_data , [color_col , marker_col ]
96165 )
97166
98167 app = JupyterDash (__name__ )
@@ -143,8 +212,16 @@ def display_hover(hoverData, value):
143212 num = pt ["pointNumber" ]
144213 curve_num = pt ["curveNumber" ]
145214
215+ # print(hoverData)
216+ # print(pt)
217+
146218 if len (fig .data ) != 1 :
147- df_curve = df [df [color_col ] == curve_dict [curve_num ]].reset_index (drop = True )
219+ # TODO replace with query
220+ # df_curve = df_grouped.get_group(curve_dict[curve_num]).reset_index(
221+ # drop=True
222+ # )
223+ df_curve = curve_dict [curve_num ].reset_index (drop = True )
224+ # df_curve = df[df[color_col] == curve_dict[curve_num]]
148225 df_row = df_curve .iloc [num ]
149226 else :
150227 df_row = df .iloc [num ]
@@ -197,6 +274,8 @@ def display_hover(hoverData, value):
197274 title = textwrap .fill (title , width = wraplen )
198275 else :
199276 title = title [:wraplen ] + "..."
277+
278+ # TODO colorbar color titles
200279 hoverbox_elements .append (
201280 html .H4 (
202281 f"{ title } " ,
0 commit comments