import pandas as pd import plotly.express as px def build_bias_distribution_chart(summary: dict): rows = [] for source, stats in summary.items(): biased = stats.get("Biased", 0) not_biased = stats.get("Not Biased", stats.get("Not_Biased", 0)) total = stats.get("total", biased + not_biased) rows.append( { "Source": source, "Biased": biased, "Not biased": not_biased, "Total": total, } ) df = pd.DataFrame(rows) if df.empty: return None df = df.sort_values("Total", ascending=False) df_melted = df.melt( id_vars=["Source", "Total"], value_vars=["Biased", "Not biased"], var_name="Classification", value_name="Articles", ) fig = px.bar( df_melted, x="Source", y="Articles", color="Classification", barmode="group", text="Articles", color_discrete_map={ "Biased": "#c24138", "Not biased": "#247857", }, ) fig.update_traces( textposition="outside", marker_line_width=0, cliponaxis=False, ) fig.update_layout( height=430, margin=dict(l=12, r=12, t=24, b=12), paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", bargap=0.26, legend=dict( orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1, title=None, ), xaxis=dict( title=None, tickangle=-20, showgrid=False, linecolor="#d8dee9", ), yaxis=dict( title="Articles", gridcolor="#e8edf4", zeroline=False, ), font=dict(color="#15202b", family="Arial, sans-serif"), ) return fig def build_lean_bias_chart(results: list) -> object: from collections import defaultdict lean_counts = defaultdict(lambda: {"Biased": 0, "Not biased": 0}) for article in results: lean = article.get("source_bias", "Unknown") label = article.get("text_label", "Unknown") if label == "Biased": lean_counts[lean]["Biased"] += 1 elif label == "Not Biased": lean_counts[lean]["Not biased"] += 1 rows = [] for lean, counts in lean_counts.items(): rows.append({ "Lean": lean, "Biased": counts["Biased"], "Not biased": counts["Not biased"], }) df = pd.DataFrame(rows) if df.empty: return None lean_order = ["Left", "Center-Left", "Center", "Center-Right", "Right", "Unknown"] df["Lean"] = pd.Categorical(df["Lean"], categories=lean_order, ordered=True) df = df.sort_values("Lean") df_melted = df.melt( id_vars="Lean", value_vars=["Biased", "Not biased"], var_name="Classification", value_name="Articles", ) fig = px.bar( df_melted, x="Lean", y="Articles", color="Classification", barmode="group", text="Articles", color_discrete_map={"Biased": "#c24138", "Not biased": "#247857"}, ) fig.update_traces(textposition="outside", marker_line_width=0, cliponaxis=False) fig.update_layout( height=380, margin=dict(l=12, r=12, t=24, b=12), paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", bargap=0.3, legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1, title=None), xaxis=dict(title=None, showgrid=False, linecolor="#d8dee9"), yaxis=dict(title="Articles", gridcolor="#e8edf4", zeroline=False), font=dict(color="#15202b", family="Arial, sans-serif"), ) return fig