Fix layout flickering, workflow, and rename branch to main
Browse files- Add use_container_width=True to all st.pyplot calls to prevent layout oscillation
- Guard demo dataset re-loading to avoid redundant reads every rerun
- Fix keep-alive workflow: fetch-depth 0, proper HF remote auth
- Replace deprecated width=stretch with use_container_width on st.dataframe
- Acknowledge vibe-coding with Claude Code in README
- .github/workflows/keep_alive.yml +5 -1
- README.md +4 -0
- app.py +9 -6
.github/workflows/keep_alive.yml
CHANGED
|
@@ -10,6 +10,8 @@ jobs:
|
|
| 10 |
runs-on: ubuntu-latest
|
| 11 |
steps:
|
| 12 |
- uses: actions/checkout@v4
|
|
|
|
|
|
|
| 13 |
|
| 14 |
- name: Generate heartbeat CSV
|
| 15 |
run: |
|
|
@@ -32,4 +34,6 @@ jobs:
|
|
| 32 |
env:
|
| 33 |
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 34 |
run: |
|
| 35 |
-
git
|
|
|
|
|
|
|
|
|
| 10 |
runs-on: ubuntu-latest
|
| 11 |
steps:
|
| 12 |
- uses: actions/checkout@v4
|
| 13 |
+
with:
|
| 14 |
+
fetch-depth: 0
|
| 15 |
|
| 16 |
- name: Generate heartbeat CSV
|
| 17 |
run: |
|
|
|
|
| 34 |
env:
|
| 35 |
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 36 |
run: |
|
| 37 |
+
git remote add hf "https://fmegahed:${HF_TOKEN}@huggingface.co/spaces/fmegahed/timeseries_visualization" || \
|
| 38 |
+
git remote set-url hf "https://fmegahed:${HF_TOKEN}@huggingface.co/spaces/fmegahed/timeseries_visualization"
|
| 39 |
+
git push hf HEAD:main --force
|
README.md
CHANGED
|
@@ -26,3 +26,7 @@ interpretation.
|
|
| 26 |
|
| 27 |
All data processing happens in-memory. No data is persisted to disk.
|
| 28 |
Only chart PNG images (never raw data) are sent to the AI when you click "Interpret."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
All data processing happens in-memory. No data is persisted to disk.
|
| 28 |
Only chart PNG images (never raw data) are sent to the AI when you click "Interpret."
|
| 29 |
+
|
| 30 |
+
## Acknowledgments
|
| 31 |
+
|
| 32 |
+
This app was vibe-coded with [Claude Code](https://docs.anthropic.com/en/docs/claude-code).
|
app.py
CHANGED
|
@@ -260,7 +260,10 @@ with st.sidebar:
|
|
| 260 |
st.session_state._upload_id = file_id
|
| 261 |
st.caption(f"Detected delimiter: `{repr(st.session_state._upload_delim)}`")
|
| 262 |
elif demo_choice != "(none)":
|
| 263 |
-
|
|
|
|
|
|
|
|
|
|
| 264 |
# else: keep whatever was already in session state
|
| 265 |
|
| 266 |
raw_df: pd.DataFrame | None = st.session_state.raw_df
|
|
@@ -451,7 +454,7 @@ with tab_single:
|
|
| 451 |
n_colors = max(12, len(y_cols))
|
| 452 |
palette_colors = get_palette_colors(palette_name, n_colors)
|
| 453 |
swatch_fig = render_palette_preview(palette_colors[:8])
|
| 454 |
-
st.pyplot(swatch_fig)
|
| 455 |
|
| 456 |
# Color-by control (for colored markers chart)
|
| 457 |
color_by = None
|
|
@@ -589,7 +592,7 @@ with tab_single:
|
|
| 589 |
st.error(f"Chart error: {exc}")
|
| 590 |
|
| 591 |
if fig is not None:
|
| 592 |
-
st.pyplot(fig)
|
| 593 |
|
| 594 |
# ---- Summary stats expander -------------------------------------------
|
| 595 |
with st.expander("Summary Statistics", expanded=False):
|
|
@@ -658,7 +661,7 @@ with tab_few:
|
|
| 658 |
style_dict=style_dict,
|
| 659 |
palette_colors=palette_b,
|
| 660 |
)
|
| 661 |
-
st.pyplot(fig_panel)
|
| 662 |
except Exception as exc:
|
| 663 |
st.error(f"Panel chart error: {exc}")
|
| 664 |
|
|
@@ -676,7 +679,7 @@ with tab_few:
|
|
| 676 |
"trend_slope": "{:,.4f}",
|
| 677 |
"adf_pvalue": "{:.4f}",
|
| 678 |
}),
|
| 679 |
-
|
| 680 |
)
|
| 681 |
|
| 682 |
# ===================================================================
|
|
@@ -726,6 +729,6 @@ with tab_many:
|
|
| 726 |
style_dict=style_dict,
|
| 727 |
palette_colors=palette_c,
|
| 728 |
)
|
| 729 |
-
st.pyplot(fig_spag)
|
| 730 |
except Exception as exc:
|
| 731 |
st.error(f"Spaghetti chart error: {exc}")
|
|
|
|
| 260 |
st.session_state._upload_id = file_id
|
| 261 |
st.caption(f"Detected delimiter: `{repr(st.session_state._upload_delim)}`")
|
| 262 |
elif demo_choice != "(none)":
|
| 263 |
+
demo_key = ("demo", demo_choice)
|
| 264 |
+
if st.session_state.get("_upload_id") != demo_key:
|
| 265 |
+
st.session_state.raw_df = _load_demo(_DEMO_FILES[demo_choice])
|
| 266 |
+
st.session_state._upload_id = demo_key
|
| 267 |
# else: keep whatever was already in session state
|
| 268 |
|
| 269 |
raw_df: pd.DataFrame | None = st.session_state.raw_df
|
|
|
|
| 454 |
n_colors = max(12, len(y_cols))
|
| 455 |
palette_colors = get_palette_colors(palette_name, n_colors)
|
| 456 |
swatch_fig = render_palette_preview(palette_colors[:8])
|
| 457 |
+
st.pyplot(swatch_fig, use_container_width=True)
|
| 458 |
|
| 459 |
# Color-by control (for colored markers chart)
|
| 460 |
color_by = None
|
|
|
|
| 592 |
st.error(f"Chart error: {exc}")
|
| 593 |
|
| 594 |
if fig is not None:
|
| 595 |
+
st.pyplot(fig, use_container_width=True)
|
| 596 |
|
| 597 |
# ---- Summary stats expander -------------------------------------------
|
| 598 |
with st.expander("Summary Statistics", expanded=False):
|
|
|
|
| 661 |
style_dict=style_dict,
|
| 662 |
palette_colors=palette_b,
|
| 663 |
)
|
| 664 |
+
st.pyplot(fig_panel, use_container_width=True)
|
| 665 |
except Exception as exc:
|
| 666 |
st.error(f"Panel chart error: {exc}")
|
| 667 |
|
|
|
|
| 679 |
"trend_slope": "{:,.4f}",
|
| 680 |
"adf_pvalue": "{:.4f}",
|
| 681 |
}),
|
| 682 |
+
use_container_width=True,
|
| 683 |
)
|
| 684 |
|
| 685 |
# ===================================================================
|
|
|
|
| 729 |
style_dict=style_dict,
|
| 730 |
palette_colors=palette_c,
|
| 731 |
)
|
| 732 |
+
st.pyplot(fig_spag, use_container_width=True)
|
| 733 |
except Exception as exc:
|
| 734 |
st.error(f"Spaghetti chart error: {exc}")
|