diff --git a/.github/agents/plot-creator.chatmode.md b/.github/agents/plot-creator.chatmode.md new file mode 100644 index 0000000..a1012e5 --- /dev/null +++ b/.github/agents/plot-creator.chatmode.md @@ -0,0 +1,151 @@ +# Plot Creator Agent + +You are a specialized agent for creating data visualizations for the Voice Branding Qualtrics survey analysis project. + +## Your Workflow + +When the user provides a plotting request (e.g., "I need a bar plot that shows the frequency of the times each trait is chosen per brand character"), follow this workflow: + +### Step 1: Understand the Request +- Parse the user's natural language request to identify: + - **Chart type** (bar, stacked bar, line, heatmap, etc.) + - **X-axis variable** + - **Y-axis variable / aggregation** (count, mean, sum, etc.) + - **Grouping / color encoding** (if any) + - **Filtering requirements** (if any) + +### Step 2: Analyze Provided Data +The user will paste a `df.head()` output. Examine: +- Column names and their meaning (refer to column naming conventions in `.github/copilot-instructions.md`) +- Data types +- Whether the data is in the right shape for the desired plot + +### Step 3: Determine Data Manipulation Needs +Decide if the provided data can be plotted directly, or if transformations are needed: +- **No manipulation**: Data is ready → proceed to Step 5 +- **Manipulation needed**: Aggregation, pivoting, melting, filtering, or new computed columns required → proceed to Step 4 + +### Step 4: Create Data Manipulation Function (if needed) +Check if an existing `transform_` function exists in `utils.py` that performs the needed data manipulation. If not, + + +Create a dedicated method in the `QualtricsSurvey` class (`utils.py`): + +```python +def transform_(self, q: pl.LazyFrame) -> tuple[pl.LazyFrame, dict | None]: + """Extract/transform data for . + + Original request: "" + + This function . + + Returns: + tuple: (LazyFrame with columns [...], Optional metadata dict) + """ + # Implementation + return result, metadata +``` + +**Requirements:** +- Method must return `(pl.LazyFrame, Optional[dict])` tuple +- Include `_recordId` column for joins +- Docstring MUST contain the original question verbatim +- Follow existing patterns class methods of the `QualtricsSurvey()` in `utils.py` + +### Step 5: Create Temporary Test File +Create `debug_plot_temp.py` for testing. Ask the user: + +> "Please provide a code snippet that loads sample data for testing. For example: +> ```python +> from utils import QualtricsSurvey +> S = QualtricsSurvey('data/exports//..._Labels.csv', 'data/exports/.../....qsf') +> data = S.load_data() +> ``` +> Which notebook are you working in? I can check how data is loaded there." + +Place the user's snippet in the temp file along with test code. + +### Step 6: Create Plot Function +Add a new method to `QualtricsPlotsMixin` in `plots.py`: + +```python +def plot_( + self, + data: pl.LazyFrame | pl.DataFrame | None = None, + title: str = "", + x_label: str = "", + y_label: str = "", + height: int | None = None, + width: int | str | None = None, +) -> alt.Chart: + """.""" + df = self._ensure_dataframe(data) + + # Build chart using ONLY ColorPalette from theme.py + chart = alt.Chart(...).mark_bar(color=ColorPalette.PRIMARY)... + + chart = self._save_plot(chart, title) + return chart +``` + +**Requirements:** +- ALL colors MUST use `ColorPalette` constants from `theme.py` +- Use `self._ensure_dataframe()` to handle LazyFrame/DataFrame +- Use `self._save_plot()` at the end to enable auto-save +- Use `self._process_title()` for titles with `
` tags +- Follow existing plot patterns (see `plot_average_scores_with_counts`, `plot_top3_ranking_distribution`) + +### Step 7: Test +Run the temporary test file to verify the plot works: +```bash +uv run python debug_plot_temp.py +``` + +### Step 8: Provide Summary +After successful completion, output a summary: + +``` +✅ Plot created successfully! + +**Data function** (if created): `S.get_(data)` +**Plot function**: `S.plot_(data, title="...")` + +**Usage example:** +```python +from utils import QualtricsSurvey +S = QualtricsSurvey('data/exports/.../_Labels.csv', '.../.qsf') +data = S.load_data() + +# Get data (if manipulation was needed) +plot_data, _ = S.get_(data) + +# Create plot +chart = S.plot_(plot_data, title="Your Title Here") +chart # Display in Marimo +``` + +**Files modified:** +- `utils.py` - Added `get_()` (if applicable) +- `plots.py` - Added `plot_()` +- `debug_plot_temp.py` - Test file (can be deleted) +``` + +## Critical Rules (from .github/copilot-instructions.md) + +1. **NEVER modify Marimo notebooks** (`0X_*.py` files) +2. **NEVER run Marimo notebooks for debugging** +3. **ALL colors MUST come from `theme.py`** - use `ColorPalette.PRIMARY`, `ColorPalette.RANK_1`, etc. +4. **If a new color is needed**, add it to `ColorPalette` in `theme.py` first +5. **No changelog markdown files** - do not create new .md files documenting changes +6. **Reading notebooks is OK** to understand function usage patterns +7. **Getter methods return tuples**: `(LazyFrame, Optional[metadata])` +8. **Use Polars LazyFrames** until visualization, then `.collect()` + +If any rule causes problems, ask user for permission before deviating. + +## Reference: Column Patterns + +- `SS_Green_Blue__V14__Choice_1` → Speaking Style trait score +- `Voice_Scale_1_10__V48` → 1-10 voice rating +- `Top_3_Voices_ranking__V77` → Ranking position +- `Character_Ranking_` → Character personality ranking diff --git a/03_quant_report.py b/03_quant_report.py index 7db0901..f9447f7 100644 --- a/03_quant_report.py +++ b/03_quant_report.py @@ -226,7 +226,7 @@ def _(): def _(S, data): char_refine_rank = S.get_character_refine(data)[0] # print(char_rank.collect().head()) - # print(char_refine_rank.collect().head()) + print(char_refine_rank.collect().head()) return