@@ -50,6 +50,15 @@ def test_groups(fig: Figure, df_grouped: DataFrameGroupBy):
5050 return True
5151
5252
53+ def find_correct_column_order (cols , col_names ):
54+
55+ correctly_ordered_cols = []
56+ for col in col_names :
57+ if col in cols :
58+ correctly_ordered_cols .append (col )
59+ return correctly_ordered_cols
60+
61+
5362def find_grouping (
5463 fig : Figure , df_data : pd .DataFrame , cols : list [str ]
5564) -> tuple [DataFrameGroupBy , dict ]:
@@ -62,6 +71,7 @@ def find_grouping(
6271 f"marker_col/color_col/facet_col is misspecified because the specified dataframe grouping names { cols } don't match the names in the plotly figure { col_names } ." ,
6372 )
6473
74+ cols = find_correct_column_order (cols , col_names )
6575 df_grouped = df_data .groupby (cols )
6676
6777 str_groups = {}
@@ -77,16 +87,24 @@ def find_grouping(
7787 curve_name = ", " .join (str (x ) for x in curve_name )
7888 if "%{x}" in curve_name :
7989 unique_x_values = np .unique (data .x )
80- if len (unique_x_values ) == 1 :
90+ if len (unique_x_values ) == 1 and len ( data . x ) != 1 :
8191 curve_name = curve_name .replace ("%{x}" , str (unique_x_values [0 ]))
8292 else :
8393 curve_name = curve_name .replace (", %{x}" , "" )
8494 if "%{y}" in curve_name :
8595 unique_y_values = np .unique (data .y )
86- if len (unique_y_values ) == 1 :
96+ if len (unique_y_values ) == 1 and len ( data . y ) != 1 :
8797 curve_name = curve_name .replace ("%{y}" , str (unique_y_values [0 ]))
8898 else :
8999 curve_name = curve_name .replace (", %{y}" , "" )
100+ if "%{marker.size}" in curve_name :
101+ unique_size_values = np .unique (data .marker .size )
102+ if len (unique_size_values ) == 1 and len (data .marker .size ) != 1 :
103+ curve_name = curve_name .replace (
104+ "%{marker.size}" , str (unique_size_values [0 ])
105+ )
106+ else :
107+ curve_name = curve_name .replace (", %{marker.size}" , "" )
90108 curve_dict [index ] = str_groups [curve_name ]
91109
92110 return df_grouped , curve_dict
@@ -133,6 +151,7 @@ def add_molecules(
133151 caption_cols : list [str ] = None ,
134152 caption_transform : dict [str , Callable ] = {},
135153 color_col : str = None ,
154+ symbol_col : str = None ,
136155 marker_col : str = None ,
137156 facet_col : str = None ,
138157 wrap : bool = True ,
@@ -179,8 +198,8 @@ def add_molecules(
179198 the key must correspond to one of the columns in subset or tooltip (default {}).
180199 color_col : str, optional
181200 name of the column in df that is used to color the datapoints in df - necessary when there is discrete conditional coloring (default None).
182- marker_col : str, optional
183- name of the column in df that is used to determine the marker shape of the datapoints in df (default None).
201+ symbol_col : str, optional
202+ name of the column in df that is used to determine the symbols of the datapoints in df (default None).
184203 facet_col : str, optional
185204 name of the column in df that is used to facet the data to multiple plots (default None).
186205 wrap : bool, optional
@@ -197,8 +216,8 @@ def add_molecules(
197216 df_data = df .copy ()
198217 if color_col is not None :
199218 df_data [color_col ] = df_data [color_col ].astype (str )
200- if marker_col is not None :
201- df_data [marker_col ] = df_data [marker_col ].astype (str )
219+ if symbol_col is not None :
220+ df_data [symbol_col ] = df_data [symbol_col ].astype (str )
202221 if facet_col is not None :
203222 df_data [facet_col ] = df_data [facet_col ].astype (str )
204223
@@ -209,10 +228,11 @@ def add_molecules(
209228
210229 if color_col is not None :
211230 cols .append (color_col )
212- if marker_col is not None :
213- cols .append (marker_col )
231+ if symbol_col is not None :
232+ cols .append (symbol_col )
214233 if facet_col is not None :
215234 cols .append (facet_col )
235+ cols = list (set (cols ))
216236 _ , curve_dict = find_grouping (fig , df_data , cols )
217237 else :
218238 colors = {0 : "black" }
@@ -226,24 +246,49 @@ def add_molecules(
226246 if isinstance (mol_col , str ):
227247 mol_col = [mol_col ]
228248
229- if mol_col is not None and len (mol_col ) > 1 :
249+ if mol_col is not None :
250+ if len (mol_col ) > 1 :
251+ menu = dcc .Dropdown (
252+ options = [{"label" : x , "value" : x } for x in mol_col ],
253+ value = mol_col [0 ],
254+ multi = True ,
255+ id = "smiles-menu" ,
256+ placeholder = "Select a mol column to display" ,
257+ )
258+ else :
259+ menu = dcc .Dropdown (
260+ options = [{"label" : mol_col , "value" : mol_col }],
261+ value = mol_col ,
262+ multi = False ,
263+ id = "smiles-menu" ,
264+ disabled = True ,
265+ )
266+ elif smiles_col is not None :
267+ if len (smiles_col ) > 1 :
268+ menu = dcc .Dropdown (
269+ options = [{"label" : x , "value" : x } for x in smiles_col ],
270+ value = smiles_col [0 ],
271+ multi = True ,
272+ id = "smiles-menu" ,
273+ placeholder = "Select a SMILES column to display" ,
274+ searchable = True ,
275+ )
276+ else :
277+ menu = dcc .Dropdown (
278+ options = [{"label" : smiles_col , "value" : smiles_col }],
279+ value = smiles_col ,
280+ multi = False ,
281+ id = "smiles-menu" ,
282+ disabled = True ,
283+ )
284+ else :
230285 menu = dcc .Dropdown (
231- options = [{"label" : x , "smiles_value" : x } for x in mol_col ],
232- value = mol_col [0 ],
233- multi = True ,
286+ options = None ,
287+ value = None ,
234288 id = "smiles-menu" ,
235289 placeholder = "Select a mol column to display" ,
290+ disabled = True ,
236291 )
237- elif smiles_col is not None and len (smiles_col ) > 1 :
238- menu = dcc .Dropdown (
239- options = [{"label" : x , "smiles_value" : x } for x in smiles_col ],
240- value = smiles_col [0 ],
241- multi = True ,
242- id = "smiles-menu" ,
243- placeholder = "Select a SMILES column to display" ,
244- )
245- else :
246- menu = dcc .Store (id = "smiles-menu" , data = 0 )
247292
248293 fig_copy = go .Figure (fig )
249294 fig_copy .update_traces (hoverinfo = "none" , hovertemplate = None )
@@ -266,22 +311,22 @@ def add_molecules(
266311 ],
267312 inputs = [
268313 Input ("graph-basic-2" , "hoverData" ),
269- Input ("smiles-menu" , "smiles_value " ),
314+ Input ("smiles-menu" , "value " ),
270315 ],
271316 )
272- def display_hover (hoverData , smiles_value ):
317+ def display_hover (hoverData , value ):
273318 if hoverData is None :
274319 return False , no_update , no_update
275320
276- if smiles_value is None :
321+ if value is None :
277322 if mol_col is not None :
278- smiles_value = mol_col
323+ value = mol_col
279324 elif smiles_col is not None :
280- smiles_value = smiles_col
281- if isinstance (smiles_value , str ):
282- chosen_smiles = [smiles_value ]
325+ value = smiles_col
326+ if isinstance (value , str ):
327+ chosen_smiles = [value ]
283328 else :
284- chosen_smiles = smiles_value
329+ chosen_smiles = value
285330
286331 pt = hoverData ["points" ][0 ]
287332 bbox = pt ["bbox" ]
0 commit comments