import plotly.graph_objects as go import plotly.io as pio import os """ Simple grouped bar chart (Baseline / Improved / Target), minimal Distill-like style. Responsive, no zoom/pan, clean hover (rounded tooltip corners via post_script). """ # Data (five categories) categories = ["A", "B", "C", "D", "E"] baseline = [0.52, 0.61, 0.67, 0.73, 0.78] improved = [0.58, 0.66, 0.72, 0.79, 0.86] target = [0.60, 0.68, 0.75, 0.82, 0.90] color_base = "#64748b" # slate-500 color_improved = "#2563eb" # blue-600 color_target = "#4b5563" # gray-600 fig = go.Figure() fig.add_bar( x=categories, y=baseline, name="Baseline", marker=dict(color=color_base), offsetgroup="grp", hovertemplate="%{x}
%{fullData.name}: %{y:.3f}", ) fig.add_bar( x=categories, y=improved, name="Improved", marker=dict(color=color_improved), offsetgroup="grp", hovertemplate="%{x}
%{fullData.name}: %{y:.3f}", ) fig.add_bar( x=categories, y=target, name="Target", marker=dict(color=color_target, opacity=0.65, line=dict(color=color_target, width=1)), offsetgroup="grp", hovertemplate="%{x}
%{fullData.name}: %{y:.3f}", ) fig.update_layout( barmode="group", autosize=True, paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", margin=dict(l=28, r=12, t=8, b=28), hovermode="x unified", legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="left", x=0), xaxis=dict( showgrid=False, zeroline=False, showline=True, linecolor="rgba(0,0,0,0.25)", linewidth=1, ticks="outside", ticklen=6, tickcolor="rgba(0,0,0,0.25)", tickfont=dict(size=12, color="rgba(0,0,0,0.65)"), title=None, automargin=True, fixedrange=True, ), yaxis=dict( showgrid=False, zeroline=False, showline=True, linecolor="rgba(0,0,0,0.25)", linewidth=1, ticks="outside", ticklen=6, tickcolor="rgba(0,0,0,0.25)", tickfont=dict(size=12, color="rgba(0,0,0,0.65)"), title=None, tickformat=".2f", automargin=True, fixedrange=True, ), ) post_script = """ (function(){ var plots = document.querySelectorAll('.js-plotly-plot'); plots.forEach(function(gd){ function round(){ try { var root = gd && gd.parentNode ? gd.parentNode : document; var rects = root.querySelectorAll('.hoverlayer .hovertext rect'); rects.forEach(function(r){ r.setAttribute('rx', 8); r.setAttribute('ry', 8); }); } catch(e) {} } if (gd && gd.on){ gd.on('plotly_hover', round); gd.on('plotly_unhover', round); gd.on('plotly_relayout', round); } setTimeout(round, 0); }); })(); """ fig.write_html("../app/src/fragments/bar.html", include_plotlyjs=False, full_html=False, config={ 'displayModeBar': False, 'responsive': True, 'scrollZoom': False, })