Skip to content

feat(pygal): implement campbell-basic#4249

Merged
github-actions[bot] merged 8 commits intomainfrom
implementation/campbell-basic/pygal
Feb 15, 2026
Merged

feat(pygal): implement campbell-basic#4249
github-actions[bot] merged 8 commits intomainfrom
implementation/campbell-basic/pygal

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: campbell-basic - pygal

Implements the pygal version of campbell-basic.

File: plots/campbell-basic/implementations/pygal.py

Parent Issue: #4241


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 15, 2026

AI Review - Attempt 1/3

Image Description

The plot displays a Campbell Diagram rendered by pygal as an XY chart at 4800×2700 px on a white background. The title "campbell-basic · pygal · pyplots.ai" is centered at the top in a dark font. The X-axis is labeled "Rotational Speed (RPM)" ranging from 0 to 6000, and the Y-axis is labeled "Frequency (Hz)" ranging from 0 to 120, both with "Hz" suffix on Y tick labels and whole-number RPM ticks on X. Five natural frequency mode curves are drawn as solid lines: 1st Bending (blue, rising gently), 2nd Bending (teal, rising moderately), 1st Torsional (purple, decreasing slightly), Axial (orange, decreasing), and 2nd Torsional (dark green, rising). Three engine order excitation lines (1x, 2x, 3x EO) are drawn as dashed diagonals from the origin in three very similar light-gray shades. Red/maroon dots mark approximately 15 critical speed intersections. A two-row legend at the bottom lists all 9 series. Grid lines are subtle light gray. The EO lines are difficult to distinguish from the grid due to their similar gray tones. Overall the plot is legible and correctly structured but the visual differentiation between EO lines and grid is poor, and the color palette for the EO lines lacks contrast.

Quality Score: 72/100

Criteria Checklist

Visual Quality (22/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set (title 56, labels 42, major labels 38, legend 32). Text is readable.
  • VQ-02: No Overlap (5/6) - Legend is slightly cramped with 9 entries in 2 rows, but generally readable. Minor crowding.
  • VQ-03: Element Visibility (4/6) - Mode curves are visible but thin. Critical speed dots are well-sized. EO dashed lines blend with grid — barely distinguishable from background grid lines due to very similar gray tones.
  • VQ-04: Color Accessibility (3/4) - Mode curves use a colorblind-friendly palette. However, the three EO lines ([waterfall-basic] Basic Waterfall Chart #777, [bullet-basic] Basic Bullet Chart #999, #bbb) are near-identical grays that are hard to distinguish from each other and from the grid.
  • VQ-05: Layout & Canvas (2/4) - Plot area uses the canvas reasonably but there is moderate wasted space, especially with the bottom legend. The y-axis "Frequency (Hz)" text is somewhat tight against the left edge.
  • VQ-06: Axis Labels & Title (2/2) - Both axes have descriptive labels with units: "Rotational Speed (RPM)" and "Frequency (Hz)".

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) - Custom style with intentional color palette, white background, explicit font choices. Looks like a well-configured pygal default rather than a distinctive design. The gray EO lines are a poor aesthetic choice.
  • DE-02: Visual Refinement (4/6) - Grid is subtle, margins are set, legend is positioned at bottom. Some refinement visible (stroke widths, legend columns). However, EO lines blending with the grid undermines the polish.
  • DE-03: Data Storytelling (2/6) - Data is displayed correctly but the plot does not guide the viewer to the critical insight (critical speeds). The critical speed markers are present but lack emphasis — they use a muted dark red that doesn't pop. No visual hierarchy draws the eye to the key intersections.

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) - Correct: XY line chart with multiple mode curves, diagonal EO lines, and intersection markers.
  • SC-02: Required Features (4/4) - All spec features present: 5 mode curves with realistic names, 3 EO lines, critical speed markers, mode labels in legend, EO labels in legend.
  • SC-03: Data Mapping (3/3) - X=RPM, Y=Hz correctly assigned. All data visible within range.
  • SC-04: Title & Legend (2/3) - Title format correct. Legend labels are correct but legend is somewhat hard to parse with 9 small entries in 2 rows.

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - Shows all 5 modes with different behaviors (rising, falling, near-constant), 3 EO lines, and multiple critical speed intersections. Slight noise adds realism. Minor: all modes are relatively flat — more dramatic gyroscopic effects would better demonstrate the concept.
  • DQ-02: Realistic Context (5/5) - Rotor dynamics scenario with realistic mode names (1st Bending, 2nd Bending, 1st Torsional, Axial, 2nd Torsional) and plausible frequency ranges (25-92 Hz base).
  • DQ-03: Appropriate Scale (4/4) - RPM 0-6000 and Hz 0-120 are realistic for rotating machinery analysis.

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) - Linear flow: imports → data → style → chart → series → save. No functions or classes.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set.
  • CQ-03: Clean Imports (2/2) - Only numpy, pygal, and Style imported — all used.
  • CQ-04: Code Elegance (1/2) - Generally clean but the critical speed intersection calculation is somewhat verbose. The interpolation logic is correct but could be more concise.
  • CQ-05: Output & API (1/1) - Saves as plot.png via render_to_png.

Library Mastery (3/10)

  • LM-01: Idiomatic Usage (2/5) - Uses pygal.XY correctly with add() and stroke_style. However, the dashed line approach uses stroke_style dict which is correct but basic. Does not leverage pygal's built-in config classes or more advanced features.
  • LM-02: Distinctive Features (1/5) - Generic XY chart usage. The SVG-native rendering and HTML export are generated but not distinctive. Could have used pygal's built-in interpolation, value formatting, or custom tooltips more creatively.

Strengths

  • Correct Campbell Diagram structure with all required elements (5 modes, 3 EO lines, critical speed markers)
  • Realistic rotor dynamics data with plausible frequency ranges and mode names
  • Proper critical speed intersection calculation using sign-change detection with linear interpolation
  • Clean code structure following KISS principle with reproducible seed
  • Explicit font sizing throughout ensures readability at target resolution

Weaknesses

  • Engine order (EO) dashed lines use three nearly identical gray shades ([waterfall-basic] Basic Waterfall Chart #777, [bullet-basic] Basic Bullet Chart #999, #bbb) that are indistinguishable from each other and blend into the grid lines — this is the most significant visual defect
  • Critical speed markers lack visual emphasis — they should be the focal point of a Campbell Diagram but use a muted dark red that doesn't stand out against the mode curves
  • No visual hierarchy or storytelling — the viewer is not guided to the key insight (where resonance occurs)
  • Legend with 9 entries in 2 small rows at the bottom is hard to parse quickly
  • Library usage is generic — does not leverage pygal-distinctive features

Verdict: REJECTED

@github-actions github-actions Bot added quality:72 Quality score 72/100 ai-rejected Quality not OK, triggers update labels Feb 15, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Feb 15, 2026
Attempt 1/3 - fixes based on AI review
@github-actions
Copy link
Copy Markdown
Contributor Author

🔧 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 15, 2026

AI Review - Attempt 2/3

Image Description

The plot displays a Campbell Diagram with the title "campbell-basic · pygal · pyplots.ai" centered at the top. The X-axis is labeled "Rotational Speed (RPM)" ranging from 0 to 6,000, and the Y-axis is labeled "Frequency (Hz)" ranging from 0.0 to 120.0. Five natural frequency mode curves are rendered as smooth, gently sloping lines in distinct colors: blue (1st Bending), teal (2nd Bending), purple (1st Torsional), orange (Axial), and green (2nd Torsional). Three engine order excitation lines (1x, 2x, 3x EO) are drawn as dashed diagonals from the origin, but they appear extremely faint — nearly invisible against the white background, with very low contrast in light pastel shades. Bright red circular markers denote critical speed intersections, which are the most prominent visual element. A legend at the bottom uses 3 columns listing all 9 series. Overall the layout fills the canvas reasonably well but the faint EO lines are a major readability issue.

Quality Score: 68/100

Criteria Checklist

Visual Quality (20/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set (title=56, labels=42, major_labels=38, legend=30). Text is clearly readable.
  • VQ-02: No Overlap (6/6) - No overlapping text elements anywhere in the plot.
  • VQ-03: Element Visibility (2/6) - Engine order lines are nearly invisible — they render as extremely faint, washed-out dashed lines despite explicit stroke_style width=6. The mode curves are also thinner than expected. Critical speed markers are the only well-visible data elements.
  • VQ-04: Color Accessibility (2/4) - Mode curves use a reasonably distinguishable palette, but the EO lines being nearly invisible means the color scheme fails in practice. The red critical markers vs. red-ish 1x EO line is also a concern.
  • VQ-05: Layout & Canvas (2/4) - Plot area fills roughly 50-60% of canvas, decent margins. Some wasted space at bottom for legend, but acceptable.
  • VQ-06: Axis Labels & Title (2/2) - Both axes have descriptive labels with units: "Rotational Speed (RPM)" and "Frequency (Hz)".

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (5/8) - Custom color palette, explicit typography, white background with subtle grid. Clearly above defaults but the invisible EO lines prevent a higher score.
  • DE-02: Visual Refinement (3/6) - Subtle grid styling with custom dash patterns, guide_stroke_color set. But mode curves and EO lines lack visual weight.
  • DE-03: Data Storytelling (2/6) - Critical speed markers serve as focal points, but EO lines being invisible means the intersection story (the core purpose of a Campbell diagram) is lost. The viewer cannot easily trace where EO lines cross mode curves.

Spec Compliance (12/15)

  • SC-01: Plot Type (5/5) - Correct: Campbell diagram with mode curves, EO lines, and critical speed markers.
  • SC-02: Required Features (2/4) - Mode labels and EO labels exist only in legend, not on the curves/lines themselves as the spec requests. Critical speed markers are present. No shading of critical zones.
  • SC-03: Data Mapping (3/3) - X=RPM, Y=Frequency(Hz), correctly mapped.
  • SC-04: Title & Legend (2/3) - Title format correct: "campbell-basic · pygal · pyplots.ai". Legend labels are descriptive but the legend is small and crowded in 3 columns.

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - 5 mode curves with varying gyroscopic effects (some increase, some decrease with speed), 3 EO lines, multiple critical speed intersections. Good variety, though all modes are fairly tightly clustered in frequency.
  • DQ-02: Realistic Context (5/5) - Realistic rotordynamic scenario with plausible mode names (1st Bending, 2nd Bending, 1st Torsional, Axial, 2nd Torsional) and sensible operating range.
  • DQ-03: Appropriate Scale (4/4) - 0-6000 RPM and 0-120 Hz are realistic for rotating machinery. Mode frequencies in the 25-100 Hz range are plausible.

Code Quality (8/10)

  • CQ-01: KISS Structure (3/3) - Linear flow: imports → data → style → chart → add series → save. No functions/classes.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set at the start.
  • CQ-03: Clean Imports (2/2) - Only numpy, pygal, and pygal.style.Style — all used.
  • CQ-04: Code Elegance (1/2) - Slightly verbose with the critical speed interpolation logic, but generally clean. The strict=True in zip is a nice touch.
  • CQ-05: Output & API (1/1) - Saves both plot.html and plot.png correctly. No deprecated functions.

Library Mastery (4/10)

  • LM-01: Idiomatic Usage (3/5) - Uses pygal.XY correctly with Style customization, stroke_style, interpolate="cubic", value_formatter. Reasonable but the invisible EO lines suggest a misunderstanding of how pygal renders stroke styles.
  • LM-02: Distinctive Features (1/5) - Uses pygal's cubic interpolation and tooltip_fancy_mode, but these are fairly generic. The SVG nature of pygal isn't leveraged distinctively.

Strengths

  • Comprehensive data generation with realistic rotordynamic parameters and gyroscopic effects
  • Excellent critical speed intersection calculation using sign-change detection with linear interpolation
  • Well-structured code following KISS principles with reproducible random seed
  • All font sizes explicitly configured for the 4800x2700 canvas
  • Custom Style with intentional color palette and grid styling

Weaknesses

  • Engine order lines are nearly invisible in the rendered PNG — they appear as extremely faint, washed-out dashed lines, making the core Campbell diagram feature (EO/mode intersections) impossible to visually trace
  • Mode curves are also quite thin and lack visual weight — increasing stroke width or ensuring stroke_opacity renders properly would help
  • No direct labels on mode curves or EO lines (spec requests "Mode shapes should be labeled" and "Engine order lines should be labeled") — currently only in legend
  • Legend colors for EO lines are tiny squares that are hard to distinguish from each other

Verdict: REJECTED

@github-actions github-actions Bot added quality:68 Quality score 68/100 ai-rejected Quality not OK, triggers update labels Feb 15, 2026
@github-actions github-actions Bot added ai-attempt-2 Second repair attempt and removed ai-rejected Quality not OK, triggers update labels Feb 15, 2026
Attempt 2/3 - fixes based on AI review
@github-actions
Copy link
Copy Markdown
Contributor Author

🔧 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 15, 2026

AI Review - Attempt 3/3

Image Description

The plot displays a Campbell Diagram with the title "campbell-basic · pygal · pyplots.ai" at the top. The X-axis shows "Rotational Speed (RPM)" ranging from 0 to 6,000, and the Y-axis shows "Frequency (Hz)" from 0.0 to 130.0. Five natural frequency mode curves are rendered as thick solid lines: 1st Bending (blue, rising gently from ~25 Hz), 2nd Bending (teal, rising from ~49 Hz), 1st Torsional (purple, declining slightly from ~62 Hz), Axial (orange, declining from ~78 Hz), and 2nd Torsional (green, rising from ~92 Hz). Three engine order excitation lines are drawn as dashed diagonals from the origin: 1× EO (red dashed), 2× EO (dark blue dashed), and 3× EO (purple dashed). Large vivid red dots mark Critical Speed intersections where engine order lines cross natural frequency curves. A legend at the bottom in three columns identifies all nine series. The background is white with subtle gray grid lines. The overall layout is clean and well-proportioned.

Quality Score: 92/100

Criteria Checklist

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set (title=56, label=42, major_label=38, legend=32). All text clearly readable at full resolution.
  • VQ-02: No Overlap (6/6) - No overlapping text elements. Legend at bottom is well-organized in 3 columns.
  • VQ-03: Element Visibility (6/6) - Mode curves use stroke width 10, EO lines width 8, critical dots size 22. All well-visible and adapted to chart dimensions.
  • VQ-04: Color Accessibility (3/4) - Colors are generally distinguishable, but 2× EO dark blue (#0d47a1) is somewhat close to 1st Bending (#306998). Mitigated by different line styles (dashed vs solid). Minor deduction.
  • VQ-05: Layout Balance (4/4) - Plot fills canvas well with balanced margins. Legend compact at bottom. Good utilization of the 4800×2700 canvas.
  • VQ-06: Axis Labels & Title (2/2) - Both axes have descriptive labels with units: "Rotational Speed (RPM)" and "Frequency (Hz)".

Design Excellence (14/20)

  • DE-01: Aesthetic Sophistication (6/8) - Custom color palette with intentional hierarchy, explicit font family (DejaVu Sans), white background with subtle gray grid, custom guide stroke styling. Strong design, clearly above defaults.
  • DE-02: Visual Refinement (4/6) - Custom grid dash patterns, subtle guide colors, generous margins, clean white background. Good refinement beyond defaults.
  • DE-03: Data Storytelling (4/6) - Visual hierarchy clearly guides the reader: thick solid lines for structural modes, dashed lines for excitations, large red dots for critical intersections. The viewer immediately sees where resonance risks exist.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct Campbell Diagram: XY chart with natural frequency curves overlaid with engine order lines and critical speed markers.
  • SC-02: Required Features (4/4) - All spec features present: 5 modes with realistic labels, 3 engine order lines labeled, critical speed intersection markers with detailed info, clean legend.
  • SC-03: Data Mapping (3/3) - X=RPM, Y=Frequency(Hz). Correct assignment with proper range.
  • SC-04: Title & Legend (3/3) - Title "campbell-basic · pygal · pyplots.ai" matches required format. Legend labels correctly identify all data series.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Shows 5 modes with both increasing and decreasing frequency trends (gyroscopic effects), 3 engine orders, multiple critical speed intersections across the operating range.
  • DQ-02: Realistic Context (5/5) - Rotordynamic analysis scenario with proper engineering mode names (1st Bending, 2nd Bending, 1st Torsional, Axial, 2nd Torsional). Authentic domain vocabulary.
  • DQ-03: Appropriate Scale (4/4) - 0-6000 RPM operating range, base natural frequencies 25-92 Hz, realistic for rotating machinery. Appropriate noise level for gyroscopic variation.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Clean flow: Imports → Seed → Data generation → Style → Chart → Series → Render. No functions or classes.
  • CQ-02: Reproducibility (2/2) - np.random.seed(42) set at the start.
  • CQ-03: Clean Imports (2/2) - Only numpy, pygal, and Style imported — all used.
  • CQ-04: Code Elegance (2/2) - Clean, Pythonic code. Intersection-finding logic is appropriately complex for the task. Well-organized loops for series addition.
  • CQ-05: Output & API (1/1) - Saves as plot.png and plot.html. No deprecated API usage.

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) - Expert use of pygal.XY with Style for theming, per-series stroke_style, value_formatter lambdas, legend_at_bottom_columns, cubic interpolation, dots_size control.
  • LM-02: Distinctive Features (4/5) - Uses pygal-specific per-point label dicts for tooltips, native SVG interactivity via render_to_file HTML output, cubic interpolation mode, stroke_style dasharray per-series, tooltip_fancy_mode. Distinctly pygal patterns.

Strengths

  • Comprehensive Campbell Diagram with all required elements: 5 mode curves, 3 engine order lines, and critical speed markers with detailed intersection info
  • Excellent font sizing and styling explicitly configured for 4800×2700 resolution — all text is clearly legible
  • Effective visual hierarchy: thick solid lines for modes, dashed lines for engine orders, large red dots for critical speeds — viewer immediately understands the diagram
  • Strong use of pygal-specific features including per-point label dicts, dual output (SVG+PNG), and cubic interpolation for smooth curves
  • Realistic engineering data with proper mode naming conventions and physically plausible frequency-speed relationships

Weaknesses

  • The 2× EO dark blue dashed line (#0d47a1) is somewhat similar to the 1st Bending solid blue (#306998) — using a more contrasting color for EO lines would improve differentiation
  • Engine order lines could benefit from slightly thicker strokes or more prominent dash patterns to stand out more distinctly from the mode curves in the PNG rendering

Verdict: APPROVED

@github-actions github-actions Bot added quality:92 Quality score 92/100 ai-approved Quality OK, ready for merge labels Feb 15, 2026
@github-actions github-actions Bot merged commit 90fc2cc into main Feb 15, 2026
@github-actions github-actions Bot deleted the implementation/campbell-basic/pygal branch February 15, 2026 21:37
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:68 Quality score 68/100 quality:72 Quality score 72/100 quality:92 Quality score 92/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants