Skip to content

update(raincloud-basic): altair — fix orientation consistency#4227

Merged
github-actions[bot] merged 8 commits intomainfrom
implementation/raincloud-basic/altair
Feb 14, 2026
Merged

update(raincloud-basic): altair — fix orientation consistency#4227
github-actions[bot] merged 8 commits intomainfrom
implementation/raincloud-basic/altair

Conversation

@MarkusNeusinger
Copy link
Copy Markdown
Owner

Summary

Updated altair implementation for raincloud-basic.

Changes: Fix cloud/rain orientation so cloud (half-violin/KDE) extends UPWARD and rain (jittered points) falls DOWNWARD from each category line.

Changes

  • Fixed orientation: cloud now extends upward (positive y-direction), rain falls downward
  • Updated spec to use absolute directional terms instead of ambiguous "TOP"/"BELOW"
  • Preserved existing review strengths

Test Plan

  • Preview images uploaded to GCS staging
  • Implementation file passes ruff format/check
  • Metadata YAML updated with current versions
  • Automated review triggered

Fixes #3745


Generated with Claude Code /update command

- Replace patch-based approach with worktree method for isolating library changes
- Update steps for creating worktrees and managing library files
- Add cleanup instructions for worktrees after processing
- Include syncing main branch after PR merges
Copilot AI review requested due to automatic review settings February 14, 2026 20:29
Fix cloud/rain orientation: cloud (half-violin) extends upward, rain (jittered points) falls downward. Updated spec to clarify absolute y-direction terms.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the orientation inconsistency in the altair implementation of the raincloud-basic plot. The issue (#3745) identified that some library implementations incorrectly positioned the cloud (half-violin/KDE) and rain (jittered points) elements, violating the visual metaphor where rain should fall from a cloud.

Changes:

  • Updated specification to use absolute directional terms (ABOVE/BELOW referring to y-axis screen position) instead of ambiguous TOP/BELOW
  • Fixed altair implementation so cloud extends upward (positive y offset) and rain falls downward (negative y offset) from category baselines
  • Updated metadata with current Python version (3.14) and set quality_score to null for re-evaluation

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
plots/raincloud-basic/specification.md Clarified orientation requirements using unambiguous directional terms (ABOVE/BELOW in y-direction)
plots/raincloud-basic/metadata/altair.yaml Updated Python version to 3.14, reset quality_score to null, updated timestamp
plots/raincloud-basic/implementations/altair.py Fixed cloud/rain positioning: cloud now extends upward (positive y), rain falls downward (negative y)
.python-version Updated project Python version to 3.14.3

@@ -1,7 +1,7 @@
""" pyplots.ai
"""pyplots.ai
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring header should have a space after the opening triple quotes to match the codebase convention. Most plot implementations use """ pyplots.ai (with space) rather than """pyplots.ai (without space).

Suggested change
"""pyplots.ai
""" pyplots.ai

Copilot uses AI. Check for mistakes.
Library: altair 6.0.0 | Python 3.13.11
Quality: 90/100 | Created: 2025-12-25
Library: altair 6.0.0 | Python 3.14
Quality: /100 | Updated: 2026-02-14
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The quality score field in line 4 shows /100 which appears to be incomplete. The quality score should either be a number (e.g., 90/100) or null if not yet evaluated.

Suggested change
Quality: /100 | Updated: 2026-02-14
Quality: null | Updated: 2026-02-14

Copilot uses AI. Check for mistakes.
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 14, 2026

AI Review - Attempt 1/3

Image Description

The plot displays a horizontal raincloud chart titled "raincloud-basic · altair · pyplots.ai" with three conditions (Control, Treatment A, Treatment B) arranged vertically from bottom to top. Each condition has: a half-violin KDE cloud extending upward from the category baseline, a small box plot centered on the baseline, and jittered strip points (rain) falling below the baseline. Colors are steel blue (#306998) for Control, gold/yellow (#FFD43B) for Treatment A, and green (#4CAF50) for Treatment B. The x-axis shows "Reaction Time (ms)" from 200 to 600. A legend labeled "Condition" is placed in the upper-right corner with a white background. Category labels (Control, Treatment A, Treatment B) appear on the left side as bold text. The grid is faint with low opacity. The violins are quite tall with 0.7 opacity, and the rain points have moderate transparency. The overall layout is horizontal (landscape) with the data area filling a reasonable portion of the canvas.

Quality Score: 77/100

Criteria Checklist

Visual Quality (24/30)

  • VQ-01: Text Legibility (7/8) - Font sizes explicitly set: title 28pt, axis labels 18-22pt, legend labels 18-20pt, y-axis category labels 20pt bold. All readable. Tick labels set to 18pt. Slightly under maximum as legend title could be better balanced.
  • VQ-02: No Overlap (4/6) - The violin clouds from one category overlap significantly into adjacent categories' vertical space. Treatment A's yellow violin extends into Treatment B's region and overlaps Treatment B's rain. Control's blue violin extends into Treatment A's space. This reduces clarity.
  • VQ-03: Element Visibility (5/6) - Rain points (size=55, opacity=0.6) are visible and appropriately sized for 80 points per group. Box plots are somewhat hard to distinguish because they share the same color as the violin and rain, making the median and quartiles less prominent.
  • VQ-04: Color Accessibility (4/4) - Blue, yellow, and green are colorblind-safe and distinguishable even under deuteranopia/protanopia simulations.
  • VQ-05: Layout & Canvas (2/4) - The hconcat approach with a separate y-axis text chart creates some wasted space. The plot fills the canvas reasonably but the separate label panel adds unnecessary width, and there's some empty space at the margins.
  • VQ-06: Axis Labels & Title (2/2) - X-axis labeled "Reaction Time (ms)" with units. Y-axis has descriptive category labels.

Design Excellence (9/20)

  • DE-01: Aesthetic Sophistication (5/8) - Thoughtful color palette starting with Python Blue, custom legend styling with border/padding, configured grid opacity, removed view stroke. Above defaults but not publication-exceptional.
  • DE-02: Visual Refinement (2/6) - Grid opacity reduced (0.4), view strokeWidth=0, but spines not customized further. The inter-category overlap detracts from visual polish. Default Altair aesthetics mostly in play.
  • DE-03: Data Storytelling (2/6) - No annotations highlighting Treatment B's bimodal distribution or the difference between groups. Data is presented but the viewer must discover patterns on their own.

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) - Correct raincloud plot with half-violin, box plot, and jittered strip. All three components present.
  • SC-02: Required Features (4/4) - Horizontal orientation with categories on y-axis, half-violin cloud above baseline, box centered on baseline, rain below baseline, median/quartile in box, jitter applied, transparency on points.
  • SC-03: Data Mapping (3/3) - Categories on y-axis, reaction time values on x-axis as specified.
  • SC-04: Title & Legend (2/3) - Title format "raincloud-basic · altair · pyplots.ai" is correct. Legend present but redundant since y-axis labels already identify categories. Legend labels match data.

Data Quality (13/15)

  • DQ-01: Feature Coverage (5/6) - Three distinct distributions with different characteristics: Control (normal), Treatment A (shifted lower mean), Treatment B (bimodal). Bimodality in Treatment B is somewhat visible as a shoulder. Could be more pronounced.
  • DQ-02: Realistic Context (5/5) - Reaction times for treatment conditions in a clinical/psych experiment. Plausible values (300-550ms range), realistic group names.
  • DQ-03: Appropriate Scale (3/4) - Values are realistic for reaction times. The fixed extent [200, 600] is slightly wider than needed, creating some empty space in violin tails.

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) - Flat structure: imports → data → layers → compose → save. No functions or classes.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set at the start.
  • CQ-03: Clean Imports (2/2) - Only altair, numpy, pandas imported — all used.
  • CQ-04: Code Elegance (1/2) - The workaround of creating a separate y-axis label chart via hconcat is somewhat verbose. The double seed setting (line 14 and 37) is unnecessary — a single seed at the top would suffice. The transform_calculate for violin_pos is clever but adds complexity.
  • CQ-05: Output & API (1/1) - Saves as plot.png and plot.html.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) - Uses transform_density, transform_calculate, alt.layer, alt.hconcat — all idiomatic Altair patterns. The manual y-position approach via condition_num mapping is a reasonable workaround for Altair's limited control over layered categorical positioning.
  • LM-02: Distinctive Features (4/5) - Uses Altair's declarative transform_density for KDE computation, alt.layer for composing multiple mark types, and interactive() for zoom/pan in the HTML version. The tooltip encoding is also distinctive to Vega-Lite/Altair.

Strengths

  • Correct raincloud orientation: cloud above, box on baseline, rain below — matching the spec's visual metaphor
  • Good use of Altair's declarative transforms (transform_density, transform_calculate) to build the half-violin
  • Colorblind-safe palette with good perceptual separation between blue, yellow, and green
  • Clean data setup with realistic bimodal distribution for Treatment B
  • Interactive HTML export alongside static PNG

Weaknesses

  • Violin clouds overlap significantly between adjacent categories, reducing visual clarity — the density scaling factor (200) is too large relative to the 1-unit category spacing
  • Box plots are hard to distinguish from violin fills due to matching colors — consider darker outlines or contrasting median color that is more visible
  • No annotations or storytelling elements to highlight the bimodal distribution in Treatment B or the treatment effect
  • The hconcat workaround for y-axis labels creates a somewhat disjointed layout with potential alignment issues
  • Rain jitter range (-0.35 to -0.12) is too wide, causing rain from upper categories to encroach on lower categories' violin space

Verdict: REJECTED

@github-actions github-actions Bot added quality:77 Quality score 77/100 ai-rejected Quality not OK, triggers update labels Feb 14, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Feb 14, 2026
Attempt 1/3 - fixes based on AI review
Copilot AI review requested due to automatic review settings February 14, 2026 20:42
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings February 14, 2026 20:42
@github-actions
Copy link
Copy Markdown
Contributor

🔧 Repair Attempt 1/3

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 14, 2026

AI Review - Attempt 2/3

Image Description

The plot displays a horizontal raincloud visualization with three conditions: Control (steel blue, #306998), Treatment A (warm gold/yellow, #FFD43B), and Treatment B (fresh green, #4CAF50). Each condition shows three stacked elements: a half-violin KDE curve extending upward (the "cloud"), a box plot with dark-outlined IQR box and red median tick centered on the category baseline, and jittered strip points scattered below the baseline (the "rain"). The x-axis is labeled "Reaction Time (ms)" ranging from ~200 to ~580, with light gray grid lines. Category labels ("Control", "Treatment A", "Treatment B") are rendered as bold text on the left. Treatment B includes italic annotations highlighting its bimodal distribution with "Peak 1" and "Peak 2" labels connected by a dashed line, and a "Bimodal distribution" note above. A legend in the top-right corner shows condition-color mapping. The title reads "raincloud-basic · altair · pyplots.ai" at the top center.

Quality Score: 82/100

Criteria Checklist

Visual Quality (25/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 28pt, axis labels 22pt, tick labels 18pt, y-labels 20pt, legend title 20pt, legend labels 18pt
  • VQ-02: No Overlap (5/6) - Minor: rain points from adjacent conditions get close; bimodal annotation text is somewhat light but still readable
  • VQ-03: Element Visibility (5/6) - Rain points and clouds visible, but box plot IQR rectangles blend into the cloud fill due to matching colors; the outline helps but doesn't fully distinguish them
  • VQ-04: Color Accessibility (3/4) - Blue and green distinguishable for most colorblind types, but bright yellow (#FFD43B) has low contrast against white background
  • VQ-05: Layout Balance (3/4) - Good canvas use with left padding for labels, but x-axis range extends to 200-220 where no data exists, creating some wasted space on the left
  • VQ-06: Axis Labels & Title (2/2) - "Reaction Time (ms)" with units on x-axis, descriptive condition names on y-axis

Design Excellence (14/20)

  • DE-01: Aesthetic Sophistication (6/8) - Strong design with custom palette, intentional visual hierarchy, styled grid with low opacity, removed view strokes. Above library defaults but not quite publication-level
  • DE-02: Visual Refinement (4/6) - Subtle grid (opacity 0.35), view stroke removed, custom axis colors, generous padding. Minor refinement gaps remain
  • DE-03: Data Storytelling (4/6) - Bimodal annotation on Treatment B is genuine storytelling: labels, dashed connecting line, and note guide the viewer to a key insight

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) - Correct raincloud with all three components: half-violin cloud, box plot, jittered strip rain
  • SC-02: Required Features (4/4) - Horizontal orientation, cloud above baseline, rain below, box plot centered, median/quartile markers, jitter, alpha transparency
  • SC-03: Data Mapping (3/3) - Categories on y-axis, continuous values on x-axis as specified
  • SC-04: Title & Legend (2/3) - Title format correct. Legend present but positioned far from data in top-right corner

Data Quality (14/15)

  • DQ-01: Feature Coverage (6/6) - Three conditions with distinct distributions: normal (Control), shifted normal (Treatment A), bimodal (Treatment B)
  • DQ-02: Realistic Context (5/5) - Reaction times for treatment conditions — real, neutral scientific scenario
  • DQ-03: Appropriate Scale (3/4) - Realistic reaction time range (300-550ms), though Treatment B's second peak at ~460ms overlapping with Control's center somewhat undermines the treatment narrative

Code Quality (8/10)

  • CQ-01: KISS Structure (3/3) - Linear flow: imports → data → plot → save, no functions/classes
  • CQ-02: Reproducibility (2/2) - np.random.seed(42)
  • CQ-03: Clean Imports (2/2) - Only altair, numpy, pandas imported and all used
  • CQ-04: Code Elegance (1/2) - Verbose manual box plot computation and manual y-axis label positioning add complexity; necessary for Altair but could be streamlined
  • CQ-05: Output & API (1/1) - Saves plot.png and plot.html correctly

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of layered composition, transform_density, transform_calculate, and declarative encoding. Manual box stats computation is less idiomatic but necessary
  • LM-02: Distinctive Features (3/5) - Uses Altair-specific features: transform_density for KDE, layer composition, interactive(), tooltip encoding, HTML export. Goes beyond generic usage

Strengths

  • Correct raincloud metaphor: clouds extend upward, rain falls downward from each category baseline
  • Bimodal distribution annotation on Treatment B adds genuine data storytelling
  • All font sizes explicitly set with large, readable values
  • Three distinct distribution shapes showcase the plot type's strengths
  • Clean layered composition using Altair's declarative approach
  • Interactive HTML output alongside PNG leverages Altair's web-native strength

Weaknesses

  • Box plot IQR rectangles are hard to distinguish from the cloud fill because they share the same color; consider making the box fill white or a lighter shade with a darker stroke
  • Yellow (#FFD43B) has poor contrast against white background; consider a darker/more saturated alternative like #D4A017 or #E8A317
  • The x-axis domain extends to 200-220 where no data exists, wasting horizontal space; tightening the domain would improve data-ink ratio
  • Legend is positioned far from the data in the top-right corner; placing it closer to the plot area or integrating labels would improve readability

Verdict: REJECTED

@github-actions github-actions Bot added quality:82 Quality score 82/100 ai-rejected Quality not OK, triggers update labels Feb 14, 2026
Copilot AI review requested due to automatic review settings February 14, 2026 20:46
@github-actions github-actions Bot added the ai-attempt-2 Second repair attempt label Feb 14, 2026
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings February 14, 2026 20:46
@github-actions github-actions Bot removed the ai-rejected Quality not OK, triggers update label Feb 14, 2026
Attempt 2/3 - fixes based on AI review
Copilot AI review requested due to automatic review settings February 14, 2026 20:50
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings February 14, 2026 20:50
@github-actions
Copy link
Copy Markdown
Contributor

🔧 Repair Attempt 2/3

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 14, 2026

AI Review - Attempt 3/3

Image Description

The plot displays a horizontal raincloud plot with three conditions (Control, Treatment A, Treatment B) stacked vertically. Each condition shows three layered components: a semi-transparent half-violin (KDE cloud) extending upward above the category baseline, a white-filled box plot with dark outlines centered on the baseline (with whiskers, caps, and a red median tick), and jittered strip points (rain) scattered below the baseline. Colors are blue (#306998) for Control, dark gold (#D4A017) for Treatment A, and green (#4CAF50) for Treatment B. The x-axis reads "Reaction Time (ms)" spanning ~250–600. Red median value annotations (442, 383, 361) sit above each box plot. Treatment B's bimodal distribution is highlighted with italic "Peak 1" and "Peak 2" labels connected by a dashed line, plus a "Bimodal distribution" note above. A legend in the upper-right lists all three conditions. The title reads "raincloud-basic · altair · pyplots.ai". The overall aesthetic is clean with a subtle dashed grid, no view border, and generous spacing between categories.

Quality Score: 94/100

Criteria Checklist

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 28pt, axis title 22pt, ticks 18pt, y-labels 20pt — perfectly readable
  • VQ-02: No Overlap (6/6) - No overlapping text; bimodal annotations, median labels, and y-labels are all clearly separated
  • VQ-03: Element Visibility (6/6) - Strip points size=45 with alpha=0.5 appropriate for 80 pts/group; violins and box plots clearly visible
  • VQ-04: Color Accessibility (4/4) - Blue/gold/green palette is colorblind-safe with good luminance contrast
  • VQ-05: Layout Balance (4/4) - Plot fills canvas well, balanced margins, left padding accommodates y-labels
  • VQ-06: Axis Labels & Title (2/2) - "Reaction Time (ms)" with units on x-axis, descriptive condition names on y-axis

Design Excellence (17/20)

  • DE-01: Aesthetic Sophistication (7/8) - Custom palette, white-filled box plots with dark outlines, red median ticks, dashed grid, removed view strokes — clearly publication-ready
  • DE-02: Visual Refinement (5/6) - Subtle dashed grid at low opacity, no view border, generous whitespace, whisker caps, white box fill separating from violin
  • DE-03: Data Storytelling (5/6) - Bimodal annotation with "Peak 1"/"Peak 2" labels and connecting dashed line; median value annotations guide the viewer through key statistics

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct raincloud with all three components (half-violin, box plot, jittered strip)
  • SC-02: Required Features (4/4) - Horizontal orientation, cloud above, box on baseline, rain below, half-violin clipping, moderate jitter, point transparency, median/quartile markers
  • SC-03: Data Mapping (3/3) - Categories on y-axis, values on x-axis — correct horizontal layout
  • SC-04: Title & Legend (3/3) - Title "raincloud-basic · altair · pyplots.ai" correct; legend with proper condition labels

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Three groups with distinct distributions: normal, narrower normal, and bimodal — demonstrates variety in shape, spread, and modality
  • DQ-02: Realistic Context (5/5) - Reaction times for treatment conditions — plausible psychology/clinical trial scenario with meaningful labels
  • DQ-03: Appropriate Scale (4/4) - Reaction times 250–600ms realistic for cognitive tasks; 80 obs/group is a reasonable sample

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) - Linear flow: imports → data → box stats → layers → compose → save
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set
  • CQ-03: Clean Imports (2/2) - All imports used (altair, numpy, pandas)
  • CQ-04: Code Elegance (1/2) - Somewhat verbose with manual box stats, whisker caps, and multiple annotation layers; partly necessary for Altair but slightly over-engineered
  • CQ-05: Output & API (1/1) - Saves plot.png and plot.html, no deprecated functions

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of Altair's declarative grammar: transform_density, transform_calculate, mark_area with y2, alt.layer composition, .interactive()
  • LM-02: Distinctive Features (4/5) - transform_density for in-spec KDE, transform_calculate for computed y-positions, declarative layer composition — distinctive Vega-Lite/Altair patterns

Strengths

  • Excellent raincloud metaphor execution: cloud rises above, rain falls below, box sits on baseline — exactly as specified
  • Strong data storytelling with bimodal distribution annotations (Peak 1/Peak 2 labels, connecting arrow, explanatory note) and median value callouts
  • Publication-quality aesthetics: custom palette, white box plots with dark outlines for contrast, subtle dashed grid, clean typography hierarchy
  • Treatment B's bimodal distribution (mixed normals) is an excellent data choice that showcases what raincloud plots reveal vs. plain box plots
  • All font sizes explicitly set with a clear hierarchy (title 28pt > axis 22pt > y-labels 20pt > ticks 18pt > annotations 14-16pt)

Weaknesses

  • Code is verbose due to manual box plot statistics and whisker cap construction — could potentially be simplified if Altair supported a native box-plot layer that aligns within the raincloud layout
  • Legend is positioned with absolute pixel coordinates (legendX=1350, legendY=50) which is fragile and may not adapt well to different rendering contexts

Verdict: APPROVED

@github-actions github-actions Bot added quality:94 Quality score 94/100 ai-approved Quality OK, ready for merge labels Feb 14, 2026
Copilot AI review requested due to automatic review settings February 14, 2026 20:54
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings February 14, 2026 20:54
Copilot AI review requested due to automatic review settings February 14, 2026 20:54
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings February 14, 2026 20:54
@github-actions github-actions Bot merged commit 575aac3 into main Feb 14, 2026
3 checks passed
@github-actions github-actions Bot deleted the implementation/raincloud-basic/altair branch February 14, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt ai-attempt-2 Second repair attempt quality:77 Quality score 77/100 quality:82 Quality score 82/100 quality:94 Quality score 94/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[raincloud-basic] Inconsistent orientation across libraries

2 participants