|
|
|
@ -274,16 +274,23 @@ def select_trajectory_plot_data( |
|
|
|
if has_valid: |
|
|
|
if has_valid: |
|
|
|
plottable_parties.append(p) |
|
|
|
plottable_parties.append(p) |
|
|
|
|
|
|
|
|
|
|
|
# DEBUG: Show plottable_parties status |
|
|
|
# DEBUG: Show plottable_parties status (use logger.debug instead of print) |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] plottable_parties: {len(plottable_parties)} parties, sample={plottable_parties[:5] if plottable_parties else 'empty'}" |
|
|
|
"[TRAJ DEBUG] plottable_parties: %d parties, sample=%s", |
|
|
|
|
|
|
|
len(plottable_parties), |
|
|
|
|
|
|
|
(plottable_parties[:5] if plottable_parties else "empty"), |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
|
|
|
|
"[TRAJ DEBUG] party_centroids keys: %s", |
|
|
|
|
|
|
|
list(party_centroids.keys())[:10], |
|
|
|
) |
|
|
|
) |
|
|
|
print(f"[TRAJ DEBUG] party_centroids keys: {list(party_centroids.keys())[:10]}") |
|
|
|
|
|
|
|
if party_centroids: |
|
|
|
if party_centroids: |
|
|
|
sample_party = list(party_centroids.keys())[0] |
|
|
|
sample_party = list(party_centroids.keys())[0] |
|
|
|
sample_vals = party_centroids[sample_party] |
|
|
|
sample_vals = party_centroids[sample_party] |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] Sample party '{sample_party}' centroids: {sample_vals[:3]}..." |
|
|
|
"[TRAJ DEBUG] Sample party '%s' centroids: %s...", |
|
|
|
|
|
|
|
sample_party, |
|
|
|
|
|
|
|
sample_vals[:3], |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
fig = go.Figure() |
|
|
|
fig = go.Figure() |
|
|
|
@ -358,8 +365,10 @@ def select_trajectory_plot_data( |
|
|
|
trace_count += 1 |
|
|
|
trace_count += 1 |
|
|
|
|
|
|
|
|
|
|
|
banner_text = "Partijcentroiden niet beschikbaar — tonen individuele MP-trajecten als fallback." |
|
|
|
banner_text = "Partijcentroiden niet beschikbaar — tonen individuele MP-trajecten als fallback." |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] Fallback to MP trajectories: trace_count={trace_count}, top_mps={len(top_mps)}" |
|
|
|
"[TRAJ DEBUG] Fallback to MP trajectories: trace_count=%d, top_mps=%d", |
|
|
|
|
|
|
|
trace_count, |
|
|
|
|
|
|
|
len(top_mps), |
|
|
|
) |
|
|
|
) |
|
|
|
return fig, trace_count, banner_text |
|
|
|
return fig, trace_count, banner_text |
|
|
|
|
|
|
|
|
|
|
|
@ -400,8 +409,11 @@ def select_trajectory_plot_data( |
|
|
|
) |
|
|
|
) |
|
|
|
trace_count += 1 |
|
|
|
trace_count += 1 |
|
|
|
|
|
|
|
|
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] Final trace_count={trace_count}, plottable_parties={len(plottable_parties)}, to_plot={len(to_plot) if 'to_plot' in dir() else 'N/A'}" |
|
|
|
"[TRAJ DEBUG] Final trace_count=%d, plottable_parties=%d, to_plot=%s", |
|
|
|
|
|
|
|
trace_count, |
|
|
|
|
|
|
|
len(plottable_parties), |
|
|
|
|
|
|
|
(len(to_plot) if "to_plot" in dir() else "N/A"), |
|
|
|
) |
|
|
|
) |
|
|
|
return fig, trace_count, None |
|
|
|
return fig, trace_count, None |
|
|
|
|
|
|
|
|
|
|
|
@ -1618,16 +1630,19 @@ def choose_trajectory_title(axis_def: dict, axis: str, threshold: float = 0.65) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_trajectories_tab(db_path: str, window_size: str) -> None: |
|
|
|
def build_trajectories_tab(db_path: str, window_size: str) -> None: |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] build_trajectories_tab called — db_path={db_path}, window_size={window_size}" |
|
|
|
"[TRAJ DEBUG] build_trajectories_tab called — db_path=%s, window_size=%s", |
|
|
|
|
|
|
|
db_path, |
|
|
|
|
|
|
|
window_size, |
|
|
|
) |
|
|
|
) |
|
|
|
st.subheader("Partij Trajectories") |
|
|
|
st.subheader("Partij Trajectories") |
|
|
|
st.markdown("Hoe bewegen partijen over de tijdsvensters heen?") |
|
|
|
st.markdown("Hoe bewegen partijen over de tijdsvensters heen?") |
|
|
|
|
|
|
|
|
|
|
|
positions_by_window, axis_def = load_positions(db_path, window_size) |
|
|
|
positions_by_window, axis_def = load_positions(db_path, window_size) |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] load_positions → {len(positions_by_window)} windows, " |
|
|
|
"[TRAJ DEBUG] load_positions → %d windows, total MPs=%d", |
|
|
|
f"total MPs={sum(len(v) for v in positions_by_window.values())}" |
|
|
|
len(positions_by_window), |
|
|
|
|
|
|
|
sum(len(v) for v in positions_by_window.values()), |
|
|
|
) |
|
|
|
) |
|
|
|
if axis_def is None: |
|
|
|
if axis_def is None: |
|
|
|
axis_def = {} |
|
|
|
axis_def = {} |
|
|
|
@ -1662,9 +1677,10 @@ def build_trajectories_tab(db_path: str, window_size: str) -> None: |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
party_map = load_party_map(db_path) |
|
|
|
party_map = load_party_map(db_path) |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] load_party_map → {len(party_map)} entries, " |
|
|
|
"[TRAJ DEBUG] load_party_map → %d entries, sample=%s", |
|
|
|
f"sample={list(party_map.items())[:3]}" |
|
|
|
len(party_map), |
|
|
|
|
|
|
|
list(party_map.items())[:3], |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Add name normalization to improve matching |
|
|
|
# Add name normalization to improve matching |
|
|
|
@ -1745,8 +1761,10 @@ def build_trajectories_tab(db_path: str, window_size: str) -> None: |
|
|
|
set(party_map.get(mp) for MPs in positions_by_window.values() for mp in MPs) |
|
|
|
set(party_map.get(mp) for MPs in positions_by_window.values() for mp in MPs) |
|
|
|
- {None, "Unknown"} |
|
|
|
- {None, "Unknown"} |
|
|
|
) |
|
|
|
) |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] all_parties (raw from party_map) → {len(all_parties)} parties: {all_parties[:10]}" |
|
|
|
"[TRAJ DEBUG] all_parties (raw from party_map) → %d parties: %s", |
|
|
|
|
|
|
|
len(all_parties), |
|
|
|
|
|
|
|
all_parties[:10], |
|
|
|
) |
|
|
|
) |
|
|
|
all_parties_sorted = sorted(all_parties) |
|
|
|
all_parties_sorted = sorted(all_parties) |
|
|
|
|
|
|
|
|
|
|
|
@ -2075,7 +2093,9 @@ def build_trajectories_tab(db_path: str, window_size: str) -> None: |
|
|
|
st.text_area("select_trajectory_plot_data traceback", tb, height=240) |
|
|
|
st.text_area("select_trajectory_plot_data traceback", tb, height=240) |
|
|
|
except Exception: |
|
|
|
except Exception: |
|
|
|
pass |
|
|
|
pass |
|
|
|
print(f"[TRAJ DEBUG] helper_succeeded={helper_succeeded}") |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
|
|
|
|
"[TRAJ DEBUG] helper_succeeded=%s", helper_succeeded |
|
|
|
|
|
|
|
) |
|
|
|
if not helper_succeeded: |
|
|
|
if not helper_succeeded: |
|
|
|
for party in selected_parties: |
|
|
|
for party in selected_parties: |
|
|
|
if party not in centroids: |
|
|
|
if party not in centroids: |
|
|
|
@ -2221,9 +2241,11 @@ def build_trajectories_tab(db_path: str, window_size: str) -> None: |
|
|
|
except Exception: |
|
|
|
except Exception: |
|
|
|
pass |
|
|
|
pass |
|
|
|
try: |
|
|
|
try: |
|
|
|
print( |
|
|
|
logging.getLogger(__name__).debug( |
|
|
|
f"[TRAJ DEBUG] About to render plotly chart — trace_count={trace_count}, " |
|
|
|
"[TRAJ DEBUG] About to render plotly chart — trace_count=%d, banner=%s, fig has %d traces", |
|
|
|
f"banner={banner_text}, fig has {len(fig.data)} traces" |
|
|
|
trace_count, |
|
|
|
|
|
|
|
banner_text, |
|
|
|
|
|
|
|
len(fig.data), |
|
|
|
) |
|
|
|
) |
|
|
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
except Exception as e: |
|
|
|
except Exception as e: |
|
|
|
|