Spaces:
Sleeping
Sleeping
| import plotly.graph_objects as go | |
| import pandas as pd | |
| import numpy as np | |
| def build_figure(dataframe: pd.DataFrame) -> go.Figure: | |
| fig = go.Figure() | |
| # Condition 1 | |
| fig.add_bar( | |
| y=dataframe["Condition 1"], | |
| x=dataframe["CASRN"], | |
| name="Condition 1", | |
| orientation="v", | |
| error_y=dict( | |
| type="data", | |
| symmetric=False, | |
| array=dataframe["Cond1_err_plus"], # +x direction | |
| arrayminus=dataframe["Cond1_err_minus"], # -x direction | |
| visible=True, | |
| ), | |
| marker=dict(color="red"), | |
| ) | |
| # Condition 2 | |
| fig.add_bar( | |
| y=dataframe["Condition 2"], | |
| x=dataframe["CASRN"], | |
| name="Condition 2", | |
| orientation="v", | |
| error_y=dict( | |
| type="data", | |
| symmetric=False, | |
| array=dataframe["Cond2_err_plus"], | |
| arrayminus=dataframe["Cond2_err_minus"], | |
| visible=True, | |
| ), | |
| marker=dict(color="blue"), | |
| ) | |
| #fig.add_hline( | |
| # y=0.9, | |
| # line_width=3, | |
| # line_color="green", | |
| # line_dash="longdash" | |
| #) | |
| # --- Compute data-driven x-range (include error bars) --- | |
| x1 = dataframe["Condition 1"].to_numpy(dtype=float) | |
| x2 = dataframe["Condition 2"].to_numpy(dtype=float) | |
| # --- Compute upper bounds including error bars --- | |
| x1_max = x1 - dataframe["Cond1_err_minus"].to_numpy(dtype=float) | |
| x2_max = x2 - dataframe["Cond2_err_minus"].to_numpy(dtype=float) | |
| # Piecewise maxima across the two conditions (array length = number of CASRN) | |
| piecewise_max = np.maximum(x1_max, x2_max) | |
| # Minimum of the piecewise maxima array (ignoring NaNs) | |
| min_of_piecewise_max = np.nanmin(piecewise_max) | |
| # Fallback if everything is NaN or non-finite | |
| if not np.isfinite(min_of_piecewise_max): | |
| min_of_piecewise_max = 1.0 | |
| # Minimum y = 3 orders of magnitude below that | |
| y_min = float(min_of_piecewise_max * 1e-1) | |
| # Ensure strictly positive for log scale | |
| y_min = float(np.maximum(y_min, np.nextafter(0.0, 1.0))) | |
| fig.update_layout( | |
| barmode="group", | |
| legend=dict( | |
| orientation="h", | |
| x=0.5, | |
| xanchor="center", | |
| y=1.08, | |
| font=dict(size=18) # β legend text size | |
| ), | |
| yaxis=dict( | |
| title=dict( | |
| text=r"Fraction released", | |
| font=dict(size=18) # β axis label size | |
| ), | |
| type="log", | |
| range=[np.log10(y_min), np.log10(1.)] | |
| ), | |
| xaxis=dict( | |
| title=dict( | |
| text=r"Representative boundary chemicals (CAS)", | |
| standoff=0, # adjust: try 0β10 depending on how close you want it | |
| font = dict(size=18) # β axis label size | |
| ) | |
| ), | |
| margin=dict(l=50, r=50, t=20, b=20), | |
| autosize=False, | |
| height=600, | |
| width=800, | |
| ) | |
| fig.update_xaxes(tickfont=dict(size=14)) | |
| fig.update_yaxes(tickfont=dict(size=14)) | |
| return fig |