Skip to content

Commit 30feef7

Browse files
author
wjm41
committed
Merge branch 'release/v1.1.7'
2 parents 25b3f23 + 99af406 commit 30feef7

3 files changed

Lines changed: 77 additions & 32 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ app.run_server(mode='inline', port=8700, height=1000)
6363
| `caption_cols` | `list` | `None` | list of column names in df to be included in the hover box |
6464
| `caption_transform` | `dict` | `{}` | Functions applied to captions for formatting. The dict must follow a key: function structure where the key must correspond to one of the columns in subset or tooltip |
6565
| `color_col` | `str` | `None` | name of the column in df that is used to color the datapoints in `df` - necessary when there is discrete conditional coloring |
66-
| `marker_col` | `str` | `None` | name of the column in df that is used to determine the marker shape of the datapoints in `df` |
66+
| `symbol_col` | `str` | `None` | name of the column in df that is used to determine the marker shape of the datapoints in `df` |
6767
| `wrap` | `bool` | `True` | whether or not to wrap the title text to multiple lines if the length of the text is too long |
6868
| `wraplen` | `int` | `20` | the threshold length of the title text before wrapping begins - adjust when changing the width of the hover box |
6969
| `width` | `int` | `150` | the width in pixels of the hover box |

examples/simple_usage_and_formatting.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4728,7 +4728,7 @@
47284728
" smiles_col='smiles',\n",
47294729
" title_col='Compound ID',\n",
47304730
" color_col='dataset',\n",
4731-
" marker_col='Minimum Degree')\n",
4731+
" symbol_col='Minimum Degree')\n",
47324732
"\n",
47334733
"app_marker.run_server(mode='inline', port=8801, height=1000)\n"
47344734
]

molplotly/main.py

Lines changed: 75 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
5362
def 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

Comments
 (0)