Skip to content

feat(bokeh): implement root-locus-basic#5125

Merged
github-actions[bot] merged 7 commits intomainfrom
implementation/root-locus-basic/bokeh
Mar 20, 2026
Merged

feat(bokeh): implement root-locus-basic#5125
github-actions[bot] merged 7 commits intomainfrom
implementation/root-locus-basic/bokeh

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: root-locus-basic - bokeh

Implements the bokeh version of root-locus-basic.

File: plots/root-locus-basic/implementations/bokeh.py

Parent Issue: #4414


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 20, 2026

AI Review - Attempt 1/3

Image Description

The plot displays a root locus diagram in the complex plane for the transfer function G(s) = 1/(s(s+1)(s+3)). The title "root-locus-basic · bokeh · pyplots.ai" appears in the top-left in dark text. The x-axis is labeled "Real Axis (σ)" and the y-axis "Imaginary Axis (jω)". Three open-loop poles are marked with dark × symbols at s = 0, -1, and -3 on the real axis. Two real-axis locus segments are drawn as semi-transparent blue lines: one from -1 to 0 and another from -5.5 to -3. The complex conjugate branches are rendered in orange, departing the real axis near s ≈ -0.5 and curving outward toward the upper-right and lower-right as gain increases. Small triangle direction arrows appear on each branch. A faint dashed vertical red line at x = 0 marks the stability boundary. The background is light gray (#FAFAFA) with a subtle grid. The Bokeh toolbar is visible in the top-right corner. No constant damping ratio or natural frequency lines are present. The imaginary axis crossing diamond markers are present but blend into the orange branch and are not prominently visible.

Score: 80/100

Category Score Max
Visual Quality 26 30
Design Excellence 12 20
Spec Compliance 12 15
Data Quality 13 15
Code Quality 10 10
Library Mastery 7 10
Total 80 100

Visual Quality (26/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 72pt, axis labels 48pt, tick labels 36pt. All perfectly readable.
  • VQ-02: No Overlap (6/6) - No overlapping text or elements anywhere.
  • VQ-03: Element Visibility (3/6) - Scatter points at size=4 are very small for 4800×2700, making locus branches appear as thin lines. Direction arrows are barely visible. Imaginary axis crossing diamonds blend with the orange branch color and lack prominence.
  • VQ-04: Color Accessibility (4/4) - Blue (#306998) and orange (#E07B39) provide excellent contrast and are colorblind-safe.
  • VQ-05: Layout & Canvas (3/4) - Good use of canvas but right side (x > 1) is mostly empty wasted space. The plot data is concentrated in the left-center portion.
  • VQ-06: Axis Labels & Title (2/2) - "Real Axis (σ)" and "Imaginary Axis (jω)" are descriptive with proper symbols.

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) - Custom two-color palette, clean background, removed axis/tick lines. Above defaults but not publication-level.
  • DE-02: Visual Refinement (4/6) - Axis lines and ticks removed, subtle grid (alpha=0.15), clean #FAFAFA background. Good refinement but grid could be more intentional (e.g., only at integer values).
  • DE-03: Data Storytelling (3/6) - Stability boundary is marked (faint dashed line) and crossings indicated, but the story could be stronger. The stability boundary line is too faint (alpha=0.25). Missing damping ratio lines weakens the narrative about pole placement design.

Spec Compliance (12/15)

  • SC-01: Plot Type (5/5) - Correct root locus plot in the complex plane showing pole migration with varying gain.
  • SC-02: Required Features (2/4) - Missing constant damping ratio and natural frequency lines (spec: "dashed or light grid to indicate constant damping ratio and natural frequency lines"). Direction arrows present but very small. Real axis segments and imaginary axis crossings are present.
  • SC-03: Data Mapping (3/3) - Real/imaginary parts correctly mapped to x/y axes. All data visible.
  • SC-04: Title & Legend (2/3) - Title format correct. No legend present — with 3 branches in 2 colors, a legend identifying branch types (real-axis vs. complex conjugate) would help.

Data Quality (13/15)

  • DQ-01: Feature Coverage (5/6) - Shows multiple branches, breakaway point, complex conjugate pair, real-axis segments, and stability crossing. Missing demonstration of break-in point (not possible with this transfer function).
  • DQ-02: Realistic Context (4/5) - Classic control systems transfer function G(s) = 1/(s(s+1)(s+3)). Textbook-standard but somewhat generic.
  • DQ-03: Appropriate Scale (4/4) - Gain range 0–80 appropriate, pole locations realistic, axis ranges sensible.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Clean linear flow: imports → data computation → plot → style → save.
  • CQ-02: Reproducibility (2/2) - Fully deterministic — polynomial root finding with fixed coefficients, no randomness.
  • CQ-03: Clean Imports (2/2) - All imports are used: numpy, bokeh.io (export_png, save), models, plotting, resources.
  • CQ-04: Code Elegance (2/2) - Appropriate complexity. Root computation loop is necessary. Clean Bokeh patterns.
  • CQ-05: Output & API (1/1) - Saves as plot.png and plot.html. Current Bokeh API used.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of ColumnDataSource, figure, scatter, segment, Span, HoverTool. Could use multi_line for branches instead of scatter for smoother curves.
  • LM-02: Distinctive Features (3/5) - HoverTool with snap-to-data showing pole coordinates and gain is a genuinely useful Bokeh-specific feature. HTML export included. Active scroll wheel zoom configured.

Score Caps Applied

  • None

Strengths

  • Excellent code quality with clean, deterministic polynomial root computation
  • Good use of Bokeh-specific HoverTool for interactive pole inspection
  • Proper real-axis segment calculation following the odd-count rule
  • Clean visual design with removed axis lines and subtle grid

Weaknesses

  • Missing constant damping ratio and natural frequency lines (spec requirement)
  • Scatter points too small (size=4) — locus branches appear as thin lines, not bold curves
  • Direction arrows barely visible — need to be larger and more prominent
  • Imaginary axis crossing diamonds blend with orange branch — need distinct color or larger size
  • Stability boundary dashed line too faint (alpha=0.25) to effectively communicate the stability region
  • No legend to distinguish branch types

Issues Found

  1. SC-02 LOW: Missing damping ratio / natural frequency grid lines required by spec
    • Fix: Add circular arcs for constant ωn and radial lines for constant ζ using multi_line or arc glyphs
  2. VQ-03 LOW: Locus branch scatter points too small at size=4
    • Fix: Use multi_line glyph with line_width=3-4 for branches, or increase scatter size to 8-10
  3. VQ-03 LOW: Direction arrows and crossing markers lack prominence
    • Fix: Increase arrow triangle size to 35+, make crossing diamonds larger (40+) with a distinct color like bright red with white edge
  4. DE-03 MODERATE: Stability boundary line too faint to tell the stability story
    • Fix: Increase stability line alpha to 0.4-0.5, add text label "Stability Boundary" near the axis

AI Feedback for Next Attempt

Add the missing constant damping ratio (ζ) and natural frequency (ωn) grid lines as light arcs/radials in the left half-plane. Increase locus branch visibility by using multi_line with line_width=3 instead of tiny scatter points. Make direction arrows, crossing markers, and the stability boundary more prominent. Add a legend distinguishing real-axis segments, complex branches, poles, and stability crossings.

Verdict: REJECTED

@github-actions github-actions Bot added quality:80 Quality score 80/100 ai-rejected Quality not OK, triggers update labels Mar 20, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Mar 20, 2026
@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 Mar 20, 2026

AI Review - Attempt 2/3

Image Description

The plot displays a root locus diagram for the transfer function G(s) = 1/(s(s+1)(s+3)) on a light gray (#FAFAFA) background. The title "root-locus-basic · bokeh · pyplots.ai" is displayed prominently at the top left. The x-axis is labeled "Real Axis (σ)" and the y-axis "Imaginary Axis (jω)". Three open-loop poles are marked with dark × symbols at s = 0, −1, and −3 on the real axis. Two blue semi-transparent line segments mark the real-axis portions of the root locus: from −1 to 0 and from −5.5 to −3. Orange scatter points trace the complex conjugate branches curving away from the real axis into the upper and lower half-planes. Red diamond markers with white borders indicate the imaginary axis crossings (stability boundary) at approximately ±j1.73. A dashed red vertical line marks the imaginary axis as the stability boundary. Triangle direction arrows on each branch indicate increasing gain. Light gray radial lines from the origin show constant damping ratio contours (ζ = 0.2, 0.4, 0.6, 0.8) and semicircular arcs show natural frequency contours (ωn = 1, 2, 3, 4). A legend in the upper right identifies: Real-axis branch, Complex branches, Open-loop poles, and Stability crossing (K=12). The plot uses equal aspect ratio with axes centered around the origin.

Score: 83/100

Category Score Max
Visual Quality 26 30
Design Excellence 12 20
Spec Compliance 14 15
Data Quality 14 15
Code Quality 10 10
Library Mastery 7 10
Total 83 100

Visual Quality (26/30)

  • VQ-01: Text Legibility (7/8) — All font sizes explicitly set (72pt title, 48pt axis labels, 36pt ticks). All text clearly readable at full resolution.
  • VQ-02: No Overlap (5/6) — Generally clean layout. Legend in upper-right area has minimal overlap with data. ζ/ωn labels are small but readable.
  • VQ-03: Element Visibility (5/6) — Poles (size=40), crossings (size=30), arrows (size=25) all clearly visible. Data scatter points (size=4) are small but appropriate for density (~2000 points).
  • VQ-04: Color Accessibility (4/4) — Blue (#306998) and orange (#E07B39) are colorblind-distinguishable. Red diamonds distinguished by shape, not just color.
  • VQ-05: Layout & Canvas (3/4) — match_aspect=True preserves geometry. Some wasted space on the right side (x_range extends to +3 but data only reaches ~+1).
  • VQ-06: Axis Labels & Title (2/2) — Descriptive labels with proper symbols: "Real Axis (σ)" and "Imaginary Axis (jω)".

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — Custom two-color palette (Python Blue + complementary orange), Helvetica typography, removed axis/tick lines. Above library defaults but not publication-grade.
  • DE-02: Visual Refinement (4/6) — Axis lines and tick marks removed, subtle grid (alpha=0.15), custom background (#FAFAFA), white border fill, no outline. Good refinement effort.
  • DE-03: Data Storytelling (3/6) — Color-coded branches create basic hierarchy. Stability boundary highlighted in red. Direction arrows show gain direction. However, the plot lacks annotations at key engineering points (breakaway point, critical gain value at crossings).

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) — Correct root locus plot showing pole migration in the complex plane as gain varies.
  • SC-02: Required Features (3/4) — Open-loop poles with × markers ✓, direction arrows ✓, real-axis segments ✓, imaginary axis crossings marked ✓, ζ/ωn reference lines visible in image ✓. Minor: no open-loop zeros with ○ markers (N/A as system has no finite zeros, but spec mentions it as a general requirement).
  • SC-03: Data Mapping (3/3) — Correct complex plane mapping with real/imaginary axes.
  • SC-04: Title & Legend (3/3) — Title matches required format. Legend clearly identifies all element types with meaningful labels.

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — Shows multiple branches, real-axis segments, breakaway behavior, complex conjugate pairs, and stability crossings. Could annotate the breakaway point explicitly.
  • DQ-02: Realistic Context (5/5) — Classic transfer function G(s) = 1/(s(s+1)(s+3)) — a standard control theory example used in textbooks. Neutral, educational.
  • DQ-03: Appropriate Scale (4/4) — Gain range 0–80 well covers the critical gain K=12. Non-uniform gain spacing provides good resolution near breakaway.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — Flat script: imports → data → plot → save. No functions or classes.
  • CQ-02: Reproducibility (2/2) — Fully deterministic (np.roots on fixed coefficients, no randomness).
  • CQ-03: Clean Imports (2/2) — All imports used: numpy, bokeh.io, bokeh.models, bokeh.plotting, bokeh.resources.
  • CQ-04: Code Elegance (2/2) — Clean, well-organized. Appropriate complexity for the visualization. Routh criterion correctly applied for K_critical=12.
  • CQ-05: Output & API (1/1) — Saves plot.png via export_png and plot.html via save with CDN resources.

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Proper use of ColumnDataSource, figure(), scatter/segment methods, HoverTool configuration, Span model. Follows Bokeh patterns well.
  • LM-02: Distinctive Features (3/5) — HoverTool with snap_to_data and custom tooltips, interactive tools (pan, wheel_zoom, box_zoom), HTML export alongside PNG, Span for overlay lines. Good use of Bokeh-specific interactivity.

Score Caps Applied

  • None

Strengths

  • Mathematically correct root locus computation with proper Routh criterion analysis (K_critical=12, ω=√3)
  • All major spec features present: poles, real-axis segments, direction arrows, stability crossings, ζ/ωn reference lines
  • Good Bokeh interactivity: HoverTool shows pole coordinates and gain, interactive zoom/pan
  • Clean, deterministic code with well-organized structure
  • Thoughtful non-uniform gain spacing for better resolution near breakaway points

Weaknesses

  • Design could be elevated: no annotations at critical engineering points (breakaway point location, gain values)
  • Data storytelling is limited — the plot shows data but doesn't guide the viewer to key insights
  • Some wasted canvas space on the right side of the plot
  • Scatter point size (4) is small — slightly larger would improve visibility

Issues Found

  1. DE-03 LOW: Plot lacks annotations at key engineering points that would tell a story
    • Fix: Add text annotations for breakaway point (~s=-0.45, K≈2), label the critical gain K=12 near the stability crossings, and optionally annotate asymptote angles
  2. DE-01 MODERATE: Design is above defaults but not publication-quality
    • Fix: Consider adding a subtle color gradient along branches to encode gain magnitude, or use line_width variation to emphasize important regions
  3. VQ-05 MODERATE: Right side of canvas has empty space
    • Fix: Tighten x_range upper bound to ~1.5 instead of 3.0, or add annotations in that space
  4. SC-02 MINOR: Spec mentions showing zeros with ○ markers as a general convention
    • Fix: Even though this system has no finite zeros, adding a note or placeholder acknowledges the convention

AI Feedback for Next Attempt

To reach 90+, focus on data storytelling (DE-03): annotate the breakaway point with its gain value, label K=12 at stability crossings, and consider adding a gain colorbar or text showing the gain progression. Tighten the x_range to reduce empty space. These annotations will transform the plot from "correct diagram" to "educational visualization" that guides the viewer through the root locus analysis.

Verdict: REJECTED

@github-actions github-actions Bot added quality:83 Quality score 83/100 ai-rejected Quality not OK, triggers update labels Mar 20, 2026
@github-actions github-actions Bot added ai-attempt-2 Second repair attempt and removed ai-rejected Quality not OK, triggers update labels Mar 20, 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 Mar 20, 2026

AI Review - Attempt 3/3

Image Description

The plot displays a root locus diagram for the transfer function G(s) = 1/(s(s+1)(s+3)) on a light gray (#FAFAFA) background. The title "root-locus-basic · bokeh · pyplots.ai" appears at the top left in dark text. The x-axis is labeled "Real Axis (σ)" and the y-axis "Imaginary Axis (jω)". Three open-loop poles are marked with large dark × markers at s=0, s=-1, and s=-3 on the real axis. Two blue real-axis locus segments extend from -1 to 0 and from -5.5 to -3. Two orange complex branches curve symmetrically upward and downward from a breakaway point near σ=-0.451, crossing the imaginary axis at approximately ±j1.73. Red diamond markers highlight the jω-axis crossings with a bold red annotation "jω-crossing: K=12, ω=√3≈1.73". A blue square marker indicates the breakaway point with annotation "Breakaway: σ=-0.451, K=0.63". A small gray circle marks the centroid at σ=-1.33 with italic annotation. Faint dotted damping ratio lines (ζ=0.6, ζ=0.8 visible) radiate from the origin, and faint dotted natural frequency arcs (ωn=1, 2, 3 visible) appear as semicircles. A dashed red line along the imaginary axis indicates the stability boundary. A blue triangle arrow on one branch indicates the direction of increasing gain. The legend in the top-right lists: Real-axis locus, Complex branches, Open-loop poles, Stability crossing (K=12), and Breakaway (K=0.63).

Score: 90/100

Category Score Max
Visual Quality 26 30
Design Excellence 16 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 8 10
Total 90 100

Visual Quality (26/30)

  • VQ-01: Text Legibility (8/8) - All font sizes explicitly set: title 72pt, axis labels 48pt, ticks 36pt, annotations 24-28pt. All perfectly readable at 4800×2700.
  • VQ-02: No Overlap (5/6) - Minor overlap between legend and ωn/ζ labels in top-right area. Main content fully readable.
  • VQ-03: Element Visibility (4/6) - Locus branches visible due to point density but individual scatter points are small (size=6). Damping ratio and natural frequency guide lines are extremely faint (alpha 0.25-0.3), making them hard to discern.
  • VQ-04: Color Accessibility (4/4) - Blue (#306998) and orange (#E07B39) provide excellent colorblind-safe distinction. Red used only for stability markers with additional shape differentiation (diamonds).
  • VQ-05: Layout & Canvas (3/4) - Good canvas utilization overall. The x-range (-5.5 to 1.5) is well-chosen. Minor issue: bottom-right branch extends near the edge of the y-range.
  • VQ-06: Axis Labels & Title (2/2) - "Real Axis (σ)" and "Imaginary Axis (jω)" are descriptive with proper engineering symbols.

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (6/8) - Strong design with custom blue/orange palette, Helvetica typography throughout, clean dark-on-light color scheme. Clearly above configured defaults with intentional visual hierarchy.
  • DE-02: Visual Refinement (5/6) - Axis lines and tick marks removed. Grid very subtle (alpha=0.12). Background styled (#FAFAFA). Legend well-styled with border and background. Generous whitespace. Near-polished.
  • DE-03: Data Storytelling (5/6) - Annotations at key engineering points (jω-crossing, breakaway, centroid) tell a clear stability analysis story. Color coding distinguishes real-axis vs complex branches. Stability boundary highlighted with dashed red line. Direction arrows show gain progression.

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct root locus plot showing pole migration through the complex plane as gain varies.
  • SC-02: Required Features (4/4) - All spec features present: × markers for open-loop poles, continuous locus curves, direction arrows, real-axis segments, imaginary axis crossings prominently marked, damping ratio/natural frequency grid lines, equal axis scaling (match_aspect=True).
  • SC-03: Data Mapping (3/3) - Real part on x-axis, imaginary part on y-axis, gain parameterizes the curves correctly.
  • SC-04: Title & Legend (3/3) - Title follows exact format "root-locus-basic · bokeh · pyplots.ai". Legend labels are descriptive and match the data.

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Shows all root locus aspects: three branches diverging from poles, breakaway point on real axis, complex conjugate branches, imaginary axis crossings, asymptotic behavior at high gain.
  • DQ-02: Realistic Context (5/5) - Uses a classic control systems transfer function G(s)=1/(s(s+1)(s+3)) with proper engineering terminology. Neutral, educational context.
  • DQ-03: Appropriate Scale (4/4) - Gain range 0-80 is sensible. Poles at 0, -1, -3 are standard textbook values. Critical gain K=12 and ω=√3 are analytically correct.

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Linear flow: imports → data computation → plot creation → styling → save. No functions or classes.
  • CQ-02: Reproducibility (2/2) - Fully deterministic: analytical root computation from polynomial coefficients using np.roots().
  • CQ-03: Clean Imports (2/2) - All imports used: numpy, bokeh.io (export_png, save), bokeh.models (ColumnDataSource, HoverTool, Label, Range1d, Span), bokeh.plotting (figure), bokeh.resources (Resources).
  • CQ-04: Code Elegance (2/2) - Clean, well-organized. Appropriate complexity for the visualization. No fake UI elements.
  • CQ-05: Output & API (1/1) - Saves as plot.png via export_png. Also produces HTML export. Current Bokeh API.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of ColumnDataSource for all data, proper Bokeh figure configuration, idiomatic styling through model properties. Could leverage more high-level patterns.
  • LM-02: Distinctive Features (4/5) - HoverTool with snap_to_data for interactive pole inspection, HTML export alongside PNG, Span model for stability boundary, active_scroll configuration. These are distinctively Bokeh features.

Score Caps Applied

  • None

Strengths

  • Excellent engineering context with analytically correct data (Routh criterion, breakaway computation, asymptote centroid)
  • Strong visual storytelling through targeted annotations at key control theory points
  • Clean design with removed axis lines/ticks, subtle grid, and professional color scheme
  • Good use of Bokeh-specific features (HoverTool, HTML export, Span)
  • All spec requirements fully met including direction arrows, real-axis segments, and guide lines

Weaknesses

  • Damping ratio and natural frequency guide lines are extremely faint (alpha 0.25-0.3), reducing their utility as reference guides
  • Minor legend overlap with guide line labels in the top-right corner
  • Locus scatter points are small (size=6); slightly larger would improve visibility

Issues Found

  • None critical. Minor visual refinements noted in weaknesses.

AI Feedback for Next Attempt

N/A - implementation meets quality threshold.

Verdict: APPROVED

@github-actions github-actions Bot added quality:90 Quality score 90/100 ai-approved Quality OK, ready for merge labels Mar 20, 2026
@github-actions github-actions Bot merged commit 8ab2098 into main Mar 20, 2026
3 checks passed
@github-actions github-actions Bot deleted the implementation/root-locus-basic/bokeh branch March 20, 2026 21:51
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:80 Quality score 80/100 quality:83 Quality score 83/100 quality:90 Quality score 90/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants