From 92aba5e0e7bc698f0c22b16d3a046d509f232bce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 21 Jun 2026 09:40:48 +0000 Subject: [PATCH 1/5] feat(plotnine): implement line-stress-strain Regen from quality 90. Addressed: - Canvas: fixed figure_size to (8, 4.5) at dpi=400 for exact 3200x1800px output (was 16x9 @ dpi=300) - Theme-adaptive chrome: added PAGE_BG, INK, INK_SOFT, REGION_ALPHA tokens for light/dark - Imprint palette: main curve now uses #009E73 (position 1) instead of non-Imprint #306998 - Save filename: now plot-{THEME}.png as required (was plot.png) - Change request: reduced from 4 region bands to 3 (elastic, strain hardening, necking); yield plateau kept as critical point marker only - Text sizes: standardized geom_text to ~3mm per library guide; element_text to 12/10/8pt - 0.2% offset annotation size now consistent with other labels - Added sys.path workaround for plotnine.py naming conflict --- .../implementations/python/plotnine.py | 159 ++++++++++-------- 1 file changed, 88 insertions(+), 71 deletions(-) diff --git a/plots/line-stress-strain/implementations/python/plotnine.py b/plots/line-stress-strain/implementations/python/plotnine.py index 061f628e5f..e62384a0d5 100644 --- a/plots/line-stress-strain/implementations/python/plotnine.py +++ b/plots/line-stress-strain/implementations/python/plotnine.py @@ -1,12 +1,25 @@ -""" pyplots.ai +""" line-stress-strain: Engineering Stress-Strain Curve -Library: plotnine 0.15.3 | Python 3.14.3 -Quality: 90/100 | Created: 2026-03-20 +Library: plotnine | Language: python """ +import os +import sys + import numpy as np import pandas as pd -from plotnine import ( + + +# Work around naming conflict between plotnine.py script and plotnine package +script_dir = os.path.dirname(os.path.abspath(__file__)) +if script_dir in sys.path: + sys.path.remove(script_dir) +if "" in sys.path: + sys.path.remove("") +if "." in sys.path: + sys.path.remove(".") + +from plotnine import ( # noqa: E402 aes, annotate, coord_cartesian, @@ -21,8 +34,6 @@ ggplot, labs, scale_color_identity, - scale_fill_identity, - scale_linetype_identity, scale_size_identity, scale_x_continuous, scale_y_continuous, @@ -31,7 +42,15 @@ ) -# Data - Mild steel stress-strain curve +THEME = os.getenv("ANYPLOT_THEME", "light") +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" +REGION_ALPHA = 0.18 if THEME == "light" else 0.28 + +# Imprint palette — position 1 is always the first categorical series +IMPRINT = ["#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477", "#99B314"] + np.random.seed(42) youngs_modulus = 210000 # MPa @@ -40,11 +59,11 @@ fracture_strain = 0.35 necking_strain = 0.22 -# Elastic region (0 to yield) +# Elastic region elastic_strain = np.linspace(0, yield_stress / youngs_modulus, 40) elastic_stress = youngs_modulus * elastic_strain -# Yield plateau (short flat region for mild steel) +# Yield plateau (part of the plastic region — not a separate band per spec) plateau_strain = np.linspace(elastic_strain[-1], 0.025, 15) plateau_stress = np.full_like(plateau_strain, yield_stress) @@ -52,108 +71,106 @@ hardening_strain = np.linspace(0.025, necking_strain, 80) hardening_stress = yield_stress + (uts - yield_stress) * ((hardening_strain - 0.025) / (necking_strain - 0.025)) ** 0.45 -# Necking to fracture (stress decreases) +# Necking to fracture necking_strain_vals = np.linspace(necking_strain, fracture_strain, 40) necking_stress = ( uts - (uts - 320) * ((necking_strain_vals - necking_strain) / (fracture_strain - necking_strain)) ** 1.3 ) -# Combine all regions strain = np.concatenate([elastic_strain, plateau_strain[1:], hardening_strain[1:], necking_strain_vals[1:]]) stress = np.concatenate([elastic_stress, plateau_stress[1:], hardening_stress[1:], necking_stress[1:]]) - df = pd.DataFrame({"strain": strain, "stress": stress}) -# 0.2% offset line data - extended for better visibility +# 0.2% offset line offset = 0.002 -offset_strain_start = offset +elastic_end = yield_stress / youngs_modulus # ~0.00119 offset_strain_end = (yield_stress + 50) / youngs_modulus + offset -# Key points -yield_point_strain = yield_stress / youngs_modulus + offset +# Critical points +yield_point_strain = elastic_end + offset yield_point_stress = yield_stress -uts_strain = necking_strain -uts_stress = uts -fracture_strain_pt = fracture_strain -fracture_stress_pt = necking_stress[-1] +fracture_stress_pt = float(necking_stress[-1]) df_points = pd.DataFrame( { - "strain": [yield_point_strain, uts_strain, fracture_strain_pt], - "stress": [yield_point_stress, uts_stress, fracture_stress_pt], - "label": ["Yield Point\n(0.2% offset)", "UTS", "Fracture"], - "color": ["#C0392B", "#C0392B", "#C0392B"], - "size": [6.0, 6.0, 6.0], + "strain": [yield_point_strain, necking_strain, fracture_strain], + "stress": [yield_point_stress, uts, fracture_stress_pt], + "color": [IMPRINT[4]] * 3, + "size": [3.0, 3.0, 3.0], } ) -# Region labels - repositioned for clarity +# Region labels: 3 regions per spec (elastic, strain hardening, necking) +# Yield plateau is a critical point, not a separate shaded band df_regions = pd.DataFrame( - { - "strain": [0.005, 0.015, 0.13, 0.29], - "stress": [410, 215, 310, 370], - "label": ["Elastic", "Yield\nPlateau", "Strain\nHardening", "Necking"], - "color": ["#5D6D7E", "#5D6D7E", "#5D6D7E", "#5D6D7E"], - } + {"strain": [0.003, 0.13, 0.29], "stress": [430, 335, 385], "label": ["Elastic", "Strain\nHardening", "Necking"]} ) -# Region boundary strains for shading -elastic_end = yield_stress / youngs_modulus -plateau_end = 0.025 - -# Plot using plotnine grammar of graphics with layered composition plot = ( ggplot() - # Region shading using annotate("rect") - plotnine-distinctive feature - + annotate("rect", xmin=0, xmax=elastic_end, ymin=0, ymax=440, alpha=0.15, fill="#3498DB") - + annotate("rect", xmin=elastic_end, xmax=plateau_end, ymin=0, ymax=440, alpha=0.15, fill="#2ECC71") - + annotate("rect", xmin=plateau_end, xmax=necking_strain, ymin=0, ymax=440, alpha=0.12, fill="#F39C12") - + annotate("rect", xmin=necking_strain, xmax=fracture_strain, ymin=0, ymax=440, alpha=0.12, fill="#E74C3C") - # Main stress-strain curve - + geom_line(df, aes(x="strain", y="stress"), color="#306998", size=2.8) - # 0.2% offset line using geom_segment - plotnine-distinctive + # Three region shadings: elastic, plastic (strain hardening), necking + + annotate("rect", xmin=0, xmax=elastic_end, ymin=0, ymax=460, alpha=REGION_ALPHA, fill=IMPRINT[2]) + + annotate("rect", xmin=elastic_end, xmax=necking_strain, ymin=0, ymax=460, alpha=REGION_ALPHA, fill=IMPRINT[3]) + + annotate("rect", xmin=necking_strain, xmax=fracture_strain, ymin=0, ymax=460, alpha=REGION_ALPHA, fill=IMPRINT[4]) + # Main stress-strain curve (Imprint position 1 — first categorical series) + + geom_line(df, aes(x="strain", y="stress"), color=IMPRINT[0], size=1.0) + # 0.2% offset construction line + geom_segment( - aes(x=offset_strain_start, xend=offset_strain_end, y=0, yend=yield_stress + 50), - color="#C0392B", - size=1.2, + aes(x=offset, xend=offset_strain_end, y=0, yend=yield_stress + 50), + color=IMPRINT[4], + size=0.6, linetype="dashed", ) - # Offset label near the line - + annotate("text", x=0.012, y=60, label="0.2% offset", size=11, color="#C0392B", fontstyle="italic") - # Key points with identity scales for direct aesthetic mapping - + geom_point(df_points, aes(x="strain", y="stress", color="color", size="size"), fill="#C0392B") + + annotate("text", x=0.011, y=52, label="0.2% offset", size=3.0, color=IMPRINT[4], fontstyle="italic") + # Critical point markers + + geom_point(df_points, aes(x="strain", y="stress", color="color", size="size")) + scale_color_identity() + scale_size_identity() - # Point labels - larger text - + geom_text( - df_points, aes(x="strain", y="stress", label="label"), nudge_y=32, size=15, color="#2C3E50", fontweight="bold" + # Critical point labels — individual positions for clarity near y-axis + + annotate( + "text", + x=yield_point_strain + 0.018, + y=yield_point_stress + 22, + label="Yield Point\n(0.2% offset)", + size=3.0, + color=INK, + fontweight="bold", + ) + + annotate("text", x=necking_strain, y=uts + 28, label="UTS", size=3.0, color=INK, fontweight="bold") + + annotate( + "text", + x=fracture_strain - 0.012, + y=fracture_stress_pt + 28, + label="Fracture", + size=3.0, + color=INK, + fontweight="bold", ) - # Region labels with identity color scale - larger text - + geom_text(df_regions, aes(x="strain", y="stress", label="label", color="color"), size=14, fontstyle="italic") - + scale_fill_identity() - + scale_linetype_identity() - # Modulus annotation - larger and repositioned + # Region labels + + geom_text(df_regions, aes(x="strain", y="stress", label="label"), size=3.0, color=INK_SOFT, fontstyle="italic") + # Elastic modulus annotation + annotate( - "text", x=0.03, y=140, label=f"E = {youngs_modulus // 1000} GPa", size=16, color="#306998", fontweight="bold" + "text", x=0.028, y=145, label=f"E = {youngs_modulus // 1000} GPa", size=3.5, color=IMPRINT[2], fontweight="bold" ) + labs(x="Engineering Strain", y="Engineering Stress (MPa)", title="line-stress-strain · plotnine · pyplots.ai") + scale_x_continuous(breaks=np.arange(0, 0.40, 0.05)) + scale_y_continuous(breaks=np.arange(0, 500, 50)) - # Coordinate control - plotnine-distinctive + coord_cartesian(xlim=(0, 0.38), ylim=(0, 460)) + theme_minimal() + theme( - figure_size=(16, 9), - plot_title=element_text(size=26, weight="bold", color="#1A2530"), - axis_title=element_text(size=22, color="#2C3E50", weight="bold"), - axis_text=element_text(size=16, color="#555555"), + figure_size=(8, 4.5), + text=element_text(size=7), + plot_title=element_text(size=12, weight="bold", color=INK), + axis_title=element_text(size=10, color=INK, weight="bold"), + axis_text=element_text(size=8, color=INK_SOFT), + panel_grid_major=element_line(color=INK, size=0.3, alpha=0.15), panel_grid_major_x=element_blank(), panel_grid_minor=element_blank(), - panel_grid_major_y=element_line(color="#E8E8E8", size=0.4, alpha=0.5), - plot_background=element_rect(fill="white", color="white"), - panel_background=element_rect(fill="white", color="white"), + plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG), + panel_background=element_rect(fill=PAGE_BG), + panel_border=element_rect(color=INK_SOFT, fill=None), + axis_line=element_line(color=INK_SOFT), ) ) -# Save -plot.save("plot.png", dpi=300, verbose=False) +plot.save(f"plot-{THEME}.png", dpi=400, width=8, height=4.5, units="in", verbose=False) From 0a83f63568de2e1dab3c69c301bd66456eb1327b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 21 Jun 2026 09:41:01 +0000 Subject: [PATCH 2/5] chore(plotnine): add metadata for line-stress-strain --- .../metadata/python/plotnine.yaml | 239 ++---------------- 1 file changed, 16 insertions(+), 223 deletions(-) diff --git a/plots/line-stress-strain/metadata/python/plotnine.yaml b/plots/line-stress-strain/metadata/python/plotnine.yaml index b61f2d85ce..7ca8985d7b 100644 --- a/plots/line-stress-strain/metadata/python/plotnine.yaml +++ b/plots/line-stress-strain/metadata/python/plotnine.yaml @@ -1,228 +1,21 @@ +# Per-library metadata for plotnine implementation of line-stress-strain +# Auto-generated by impl-generate.yml + library: plotnine +language: python specification_id: line-stress-strain created: '2026-03-20T21:22:28Z' -updated: '2026-03-20T21:43:25Z' -generated_by: claude-opus-4-5-20251101 -workflow_run: 23363004971 +updated: '2026-06-21T09:41:00Z' +generated_by: claude-sonnet +workflow_run: 27900085743 issue: 4413 -python_version: 3.14.3 -library_version: 0.15.3 -preview_url: https://storage.googleapis.com/anyplot-images/plots/line-stress-strain/plotnine/plot.png -preview_html: null -quality_score: 90 +language_version: 3.13.14 +library_version: 0.15.7 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/line-stress-strain/python/plotnine/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/line-stress-strain/python/plotnine/plot-dark.png +preview_html_light: null +preview_html_dark: null +quality_score: null review: - strengths: - - Excellent data storytelling through color-coded region shading that guides the - viewer through material behavior phases - - 'All spec-required features implemented: region labels, critical points, elastic - modulus annotation, 0.2% offset line' - - Realistic mild steel data with appropriate engineering values - - Clean, well-structured code following KISS principles - - Good use of plotnine grammar-of-graphics approach with layered composition - weaknesses: - - The elastic region is horizontally compressed, creating visual density with multiple - labels in a narrow space - - The 0.2% offset annotation text (size=11) is noticeably smaller than other text - elements - image_description: 'The plot displays an engineering stress-strain curve for mild - steel on a white background. The title "line-stress-strain · plotnine · pyplots.ai" - appears in bold dark text at the top. The x-axis is labeled "Engineering Strain" - (0.00–0.35) and the y-axis "Engineering Stress (MPa)" (0–450). A thick dark blue - line traces the characteristic stress-strain path from origin through elastic - deformation, yield plateau, strain hardening up to ~400 MPa at strain ~0.22 (UTS), - then necking down to ~320 MPa at fracture (strain ~0.35). Four color-shaded rectangular - regions mark the material behavior zones: light blue (Elastic), light green (Yield - Plateau), light yellow/orange (Strain Hardening), and light pink/red (Necking), - each with gray italic region labels. Three red dots mark critical points labeled - in bold: "Yield Point (0.2% offset)", "UTS", and "Fracture". A red dashed line - shows the 0.2% offset construction with a small red italic "0.2% offset" label - near the bottom. "E = 210 GPa" appears in bold blue text. The y-axis grid is subtle - light gray; x-axis grid is removed. Layout is 16:9 with good canvas utilization.' - criteria_checklist: - visual_quality: - score: 28 - max: 30 - items: - - id: VQ-01 - name: Text Legibility - score: 7 - max: 8 - passed: true - comment: All major text sizes explicitly set (title=26, axis_title=22, axis_text=16). - The 0.2% offset annotation at size=11 is smaller than other text. - - id: VQ-02 - name: No Overlap - score: 5 - max: 6 - passed: true - comment: No actual text overlap, but elastic region is horizontally compressed - with multiple labels in a narrow band. - - id: VQ-03 - name: Element Visibility - score: 6 - max: 6 - passed: true - comment: Main curve at size=2.8 clearly visible, key points at size=6 are - prominent. - - id: VQ-04 - name: Color Accessibility - score: 4 - max: 4 - passed: true - comment: Blue curve with red accents, pastel region shading. Colorblind-safe, - no red-green dependency. - - id: VQ-05 - name: Layout & Canvas - score: 4 - max: 4 - passed: true - comment: Good 16:9 proportions with plot filling the canvas well. - - id: VQ-06 - name: Axis Labels & Title - score: 2 - max: 2 - passed: true - comment: 'Descriptive labels with units: Engineering Strain and Engineering - Stress (MPa).' - design_excellence: - score: 15 - max: 20 - items: - - id: DE-01 - name: Aesthetic Sophistication - score: 6 - max: 8 - passed: true - comment: Color-coded region shading, custom palette, intentional typographic - hierarchy. Above defaults. - - id: DE-02 - name: Visual Refinement - score: 4 - max: 6 - passed: true - comment: X-grid removed, subtle y-only grid, clean white background. Minor - density in elastic region. - - id: DE-03 - name: Data Storytelling - score: 5 - max: 6 - passed: true - comment: Color-coded regions guide viewer through material behavior. Key points - create clear focal points. - spec_compliance: - score: 15 - max: 15 - items: - - id: SC-01 - name: Plot Type - score: 5 - max: 5 - passed: true - comment: Correct engineering stress-strain curve as line plot. - - id: SC-02 - name: Required Features - score: 4 - max: 4 - passed: true - comment: 'All spec features present: region labels, critical points, modulus - annotation, offset line.' - - id: SC-03 - name: Data Mapping - score: 3 - max: 3 - passed: true - comment: X=strain, Y=stress correctly mapped with full data range. - - id: SC-04 - name: Title & Legend - score: 3 - max: 3 - passed: true - comment: Title follows exact format. No legend needed for single-series. - data_quality: - score: 15 - max: 15 - items: - - id: DQ-01 - name: Feature Coverage - score: 6 - max: 6 - passed: true - comment: 'Shows all curve regions: elastic, yield plateau, strain hardening, - necking, fracture.' - - id: DQ-02 - name: Realistic Context - score: 5 - max: 5 - passed: true - comment: Mild steel tensile test - classic, neutral engineering scenario. - - id: DQ-03 - name: Appropriate Scale - score: 4 - max: 4 - passed: true - comment: 'Realistic values for mild steel: E=210 GPa, yield=250 MPa, UTS=400 - MPa.' - code_quality: - score: 10 - max: 10 - items: - - id: CQ-01 - name: KISS Structure - score: 3 - max: 3 - passed: true - comment: 'Clean linear flow: imports, data, plot, save. No functions or classes.' - - id: CQ-02 - name: Reproducibility - score: 2 - max: 2 - passed: true - comment: np.random.seed(42) set at start. - - id: CQ-03 - name: Clean Imports - score: 2 - max: 2 - passed: true - comment: All imports are used. - - id: CQ-04 - name: Code Elegance - score: 2 - max: 2 - passed: true - comment: Well-organized with clear sections. No fake UI. - - id: CQ-05 - name: Output & API - score: 1 - max: 1 - passed: true - comment: Saves as plot.png with dpi=300. Current plotnine API. - library_mastery: - score: 7 - max: 10 - items: - - id: LM-01 - name: Idiomatic Usage - score: 4 - max: 5 - passed: true - comment: Good grammar-of-graphics with layered composition, aes mapping, identity - scales, theme customization. - - id: LM-02 - name: Distinctive Features - score: 3 - max: 5 - passed: true - comment: Uses annotate rect for region shading, coord_cartesian, identity - scales, geom_segment. - verdict: APPROVED -impl_tags: - dependencies: [] - techniques: - - annotations - - layer-composition - patterns: - - data-generation - dataprep: [] - styling: - - alpha-blending - - grid-styling + strengths: [] + weaknesses: [] From 173d4d5dcca96816b048dff0825acbc403d4aefa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 21 Jun 2026 09:47:50 +0000 Subject: [PATCH 3/5] chore(plotnine): update quality score 79 and review feedback for line-stress-strain --- .../implementations/python/plotnine.py | 5 +- .../metadata/python/plotnine.yaml | 278 +++++++++++++++++- 2 files changed, 274 insertions(+), 9 deletions(-) diff --git a/plots/line-stress-strain/implementations/python/plotnine.py b/plots/line-stress-strain/implementations/python/plotnine.py index e62384a0d5..ae02305bd7 100644 --- a/plots/line-stress-strain/implementations/python/plotnine.py +++ b/plots/line-stress-strain/implementations/python/plotnine.py @@ -1,6 +1,7 @@ -""" +""" anyplot.ai line-stress-strain: Engineering Stress-Strain Curve -Library: plotnine | Language: python +Library: plotnine 0.15.7 | Python 3.13.14 +Quality: 79/100 | Updated: 2026-06-21 """ import os diff --git a/plots/line-stress-strain/metadata/python/plotnine.yaml b/plots/line-stress-strain/metadata/python/plotnine.yaml index 7ca8985d7b..e44c441a39 100644 --- a/plots/line-stress-strain/metadata/python/plotnine.yaml +++ b/plots/line-stress-strain/metadata/python/plotnine.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for plotnine implementation of line-stress-strain -# Auto-generated by impl-generate.yml - library: plotnine language: python specification_id: line-stress-strain created: '2026-03-20T21:22:28Z' -updated: '2026-06-21T09:41:00Z' +updated: '2026-06-21T09:47:49Z' generated_by: claude-sonnet workflow_run: 27900085743 issue: 4413 @@ -15,7 +12,274 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/line-stre preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/line-stress-strain/python/plotnine/plot-dark.png preview_html_light: null preview_html_dark: null -quality_score: null +quality_score: 79 review: - strengths: [] - weaknesses: [] + strengths: + - 'Complete spec compliance: all required features implemented — elastic/strain-hardening/necking + region bands, yield point with 0.2% offset construction line, UTS marker, fracture + point, and elastic modulus annotation' + - 'Perfect data quality: realistic mild steel parameters (E=210 GPa, yield=250 MPa, + UTS=400 MPa, fracture_strain=0.35) with correct power-law hardening and necking + profile' + - 'Correct Imprint palette usage: first series (main curve) in #009E73 brand green; + region shading uses Imprint palette positions 2-4 with alpha blending; critical + point markers use semantic matte red #AE3030' + - 'Full theme-adaptive chrome: PAGE_BG, INK, INK_SOFT tokens correctly applied to + all non-data elements; both renders use correct backgrounds (#FAF8F1 light / #1A1A17 + dark)' + - 'Perfect code quality: KISS flat script, np.random.seed(42) for reproducibility, + only used imports, clean plotnine grammar-of-graphics layering' + weaknesses: + - 'SC-04 FAIL: Title reads ''line-stress-strain · plotnine · pyplots.ai'' but must + be ''line-stress-strain · python · plotnine · anyplot.ai''. Two issues: (1) ''python'' + language is missing between library and domain; (2) domain is ''pyplots.ai'' instead + of ''anyplot.ai''. Fix: labs(title=''line-stress-strain · python · plotnine · + anyplot.ai'')' + - '''Elastic'' region label (x=0.003) is positioned inside the strain-hardening + band, not the elastic region, because the elastic zone ends at ~0.00119 strain. + The label is confusingly outside its region. Fix: place label inside the narrow + elastic band (x≈0.0005, y=200) or use a small horizontal arrow/segment to connect + it' + - 'In the dark render, the ''Elastic'' region band (IMPRINT[2] #4467A3 with alpha=0.28 + on #1A1A17) creates a dark olive fill that significantly reduces chart area contrast. + The three overlapping alpha-blended bands in dark mode produce heavy, saturated + fills that compete with the data curve. Consider reducing REGION_ALPHA to 0.12-0.15 + for dark theme for a more refined look' + - Four-sided panel border (panel_border=element_rect) is kept instead of the style-guide's + recommended L-shaped frame (remove top and right spines). For an engineering chart + this is defensible, but removing top/right spines would improve visual refinement + - The '0.2% offset' italic annotation (size=3.0mm, color=IMPRINT[4]) at y=52 is + very small and in matte red (#AE3030) against the dark olive region background + in the dark render — marginally legible. Increase to size=3.5 and consider using + INK_SOFT for better contrast on both themes + - 'CVD concern: the main curve (#009E73 green) and the critical-point markers (#AE3030 + red) form a green-red pair. While they encode different chart roles (line vs. + markers), deuteranopia users may have difficulty distinguishing them. The markers + already use distinct shape (filled circle), which partially mitigates this' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white #FAF8F1 — correct per style guide. Not pure white. + Chrome: Title "line-stress-strain · plotnine · pyplots.ai" bold black, clearly readable. Axis labels "Engineering Strain" (x) and "Engineering Stress (MPa)" (y) in dark bold text, fully readable. Tick labels (0.00–0.35 on x, 0–450 on y) in dark soft color, readable. Y-axis-only horizontal grid lines are subtle and non-competing. + Data: Three colored region bands visible — a very narrow blue-tinted elastic sliver on the far left (~0 to 0.001), a beige/tan strain-hardening band (~0.001 to 0.22), and a pink/salmon necking band (0.22–0.35). Main stress-strain curve in brand green #009E73 is prominent and well-rendered with correct S-shape (elastic rise, yield plateau, strain hardening, necking). Three matte-red markers (#AE3030) at yield point (~0.003, 250 MPa), UTS (~0.22, 400 MPa), and fracture (~0.35, 320 MPa). Red dashed offset line is a nearly vertical sliver near origin. Annotations: "Yield Point (0.2% offset)" bold dark text, "UTS" bold above UTS marker, "Fracture" bold near fracture, "E = 210 GPa" in blue in lower-left, "0.2% offset" small italic red near bottom, region labels "Elastic"/"Strain\nHardening"/"Necking" in soft italic. + Legibility verdict: PASS — all text readable; "0.2% offset" is small but visible; "Elastic" label is positioned just outside the elastic region band. + + Dark render (plot-dark.png): + Background: Warm near-black #1A1A17 — correct per style guide. Not pure black. + Chrome: Title "line-stress-strain · plotnine · pyplots.ai" in bold light-cream text, clearly readable against dark background. Axis labels in adaptive light text, readable. Tick labels in soft light color (#B8B7B0 INK_SOFT), readable. Horizontal grid lines are subtle light lines, non-competing. No dark-on-dark failures for chrome elements. + Data: The three region bands produce notably heavier fills on dark — the elastic zone becomes a dark olive-blue tint, strain hardening becomes a dark olive-tan, and necking becomes a dark brownish-red. These fills are more saturated than in the light render. The green curve (#009E73) remains clearly visible as it contrasts well against all three dark band fills. The three matte-red markers remain identifiable. The "Yield Point (0.2% offset)" label appears in light cream (INK token), readable. "0.2% offset" italic red text at the bottom-left is marginally legible against the dark olive background — the matte red (#AE3030) has adequate but not generous contrast on #1A1A17. Data colors (green curve, red markers, colored bands) are identical to the light render — only chrome flips. + Legibility verdict: PASS (marginal) — all primary text is readable; "0.2% offset" italic annotation is the weakest legibility element on dark due to small size and matte red on dark background. + criteria_checklist: + visual_quality: + score: 24 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 6 + max: 8 + passed: true + comment: Title, axis labels, tick labels all readable in both themes. '0.2% + offset' annotation (size=3mm, matte red) is marginally legible in dark render. + 'Elastic' region label slightly mispositioned (in wrong band). Dock 2pts. + - id: VQ-02 + name: No Overlap + score: 5 + max: 6 + passed: true + comment: Minor crowding near yield region where offset line, yield marker, + and 'Yield Point' label are close together. No hard overlap but tight. + - id: VQ-03 + name: Element Visibility + score: 5 + max: 6 + passed: true + comment: Green curve and red markers clearly visible. Elastic region band + is a very narrow sliver that's hard to distinguish from the left axis border. + Region bands heavier in dark mode. + - id: VQ-04 + name: Color Accessibility + score: 1 + max: 2 + passed: true + comment: Green curve + red markers create a CVD-challenging pair. Shape differentiation + (line vs. dot) partially mitigates but remains a concern for deuteranopia + users. + - id: VQ-05 + name: Layout & Canvas + score: 3 + max: 4 + passed: true + comment: Canvas gate passed. Good proportions overall. Elastic region very + narrow but inherent to stress-strain physics. No overflow/clipping. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: 'X: ''Engineering Strain'' (dimensionless — correct no units), Y: + ''Engineering Stress (MPa)'' with units. Clear and descriptive.' + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series (main curve) = #009E73 brand green. Region shading + uses Imprint positions 2-4 with alpha. Critical markers use semantic matte + red #AE3030. Backgrounds #FAF8F1 light / #1A1A17 dark. Data colors identical + across themes.' + design_excellence: + score: 12 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: true + comment: 'Above default (4): thoughtful three-region color banding, multiple + annotation types, custom Imprint palette applied consistently. Below exceptional + due to heavy dark-mode region fills and no typography variations.' + - id: DE-02 + name: Visual Refinement + score: 3 + max: 6 + passed: true + comment: theme_minimal base, vertical grid disabled, minor grid only. However + panel_border keeps 4-sided border instead of L-shaped frame per style guide. + Above default (2) for horizontal-only grid. + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: 'Strong storytelling: region bands, critical point annotations, 0.2% + offset construction, E modulus annotation all guide the viewer through the + material science narrative. Above default (2).' + spec_compliance: + score: 12 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct engineering stress-strain line chart with all characteristic + regions. + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: 'All features present: region labels (elastic/strain hardening/necking), + yield point with 0.2% offset line, UTS marker, fracture point, E modulus + annotation.' + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: 'Correct: strain 0-0.35 on x, stress 0-400+ MPa on y, correct curve + shape with yield plateau and necking.' + - id: SC-04 + name: Title & Legend + score: 0 + max: 3 + passed: false + comment: 'FAIL: Title is ''line-stress-strain · plotnine · pyplots.ai''. Required + format is ''line-stress-strain · python · plotnine · anyplot.ai''. Two errors: + missing ''python'' language, wrong domain ''pyplots.ai'' vs ''anyplot.ai''.' + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: 'All aspects shown: elastic, yield plateau, strain hardening, necking, + fracture. 0.2% offset construction, modulus, critical points all present.' + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: 'Mild steel parameters are textbook-accurate: E=210 GPa, yield=250 + MPa, UTS=400 MPa, fracture_strain=0.35. Neutral engineering context, no + controversial content.' + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: 175 data points provides smooth curves. Strain 0-0.35 and stress + 0-460 MPa axes appropriate for mild steel. Tick intervals sensible. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Flat linear script, no functions or classes. Clear variable organization. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: np.random.seed(42) set. Data is deterministic. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: All imports used. sys.path manipulation necessary for plotnine.py + filename conflict. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Clean plotnine grammar-of-graphics layering. No fake UI. Appropriate + complexity for the annotation density required. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves as plot-{THEME}.png with correct dpi=400, width=8, height=4.5. + library_mastery: + score: 6 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + passed: true + comment: 'Good idiomatic plotnine: annotate() for non-data shapes, geom_segment() + for line segments, scale_color_identity() + scale_size_identity() for manual + aesthetics, coord_cartesian() for axis limits. Above default (3).' + - id: LM-02 + name: Distinctive Features + score: 2 + max: 5 + passed: true + comment: Uses annotate('rect') for region shading (ggplot2-specific), geom_text() + for vectorized labels, grammar-of-graphics layering. Above default (1) but + no advanced plotnine-specific features like faceting or complex scales. + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - annotations + - layer-composition + - manual-ticks + patterns: + - data-generation + dataprep: [] + styling: + - alpha-blending From 6fddcdc4211ce82dddb33e3292c5cc361218429c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sun, 21 Jun 2026 09:50:26 +0000 Subject: [PATCH 4/5] fix(plotnine): address review feedback for line-stress-strain Attempt 1/3 - fixes based on AI review --- .../implementations/python/plotnine.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plots/line-stress-strain/implementations/python/plotnine.py b/plots/line-stress-strain/implementations/python/plotnine.py index ae02305bd7..395ce128a2 100644 --- a/plots/line-stress-strain/implementations/python/plotnine.py +++ b/plots/line-stress-strain/implementations/python/plotnine.py @@ -1,4 +1,4 @@ -""" anyplot.ai +"""anyplot.ai line-stress-strain: Engineering Stress-Strain Curve Library: plotnine 0.15.7 | Python 3.13.14 Quality: 79/100 | Updated: 2026-06-21 @@ -47,7 +47,7 @@ PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" INK = "#1A1A17" if THEME == "light" else "#F0EFE8" INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" -REGION_ALPHA = 0.18 if THEME == "light" else 0.28 +REGION_ALPHA = 0.18 if THEME == "light" else 0.13 # Imprint palette — position 1 is always the first categorical series IMPRINT = ["#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477", "#99B314"] @@ -104,7 +104,11 @@ # Region labels: 3 regions per spec (elastic, strain hardening, necking) # Yield plateau is a critical point, not a separate shaded band df_regions = pd.DataFrame( - {"strain": [0.003, 0.13, 0.29], "stress": [430, 335, 385], "label": ["Elastic", "Strain\nHardening", "Necking"]} + { + "strain": [elastic_end / 2, 0.13, 0.29], + "stress": [350, 335, 385], + "label": ["Elastic", "Strain\nHardening", "Necking"], + } ) plot = ( @@ -122,7 +126,7 @@ size=0.6, linetype="dashed", ) - + annotate("text", x=0.011, y=52, label="0.2% offset", size=3.0, color=IMPRINT[4], fontstyle="italic") + + annotate("text", x=0.011, y=52, label="0.2% offset", size=3.5, color=INK_SOFT, fontstyle="italic") # Critical point markers + geom_point(df_points, aes(x="strain", y="stress", color="color", size="size")) + scale_color_identity() @@ -153,7 +157,11 @@ + annotate( "text", x=0.028, y=145, label=f"E = {youngs_modulus // 1000} GPa", size=3.5, color=IMPRINT[2], fontweight="bold" ) - + labs(x="Engineering Strain", y="Engineering Stress (MPa)", title="line-stress-strain · plotnine · pyplots.ai") + + labs( + x="Engineering Strain", + y="Engineering Stress (MPa)", + title="line-stress-strain · python · plotnine · anyplot.ai", + ) + scale_x_continuous(breaks=np.arange(0, 0.40, 0.05)) + scale_y_continuous(breaks=np.arange(0, 500, 50)) + coord_cartesian(xlim=(0, 0.38), ylim=(0, 460)) From 0da54bafbf89ce0b35bd9f0680f614548fa0ceee Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 21 Jun 2026 09:58:32 +0000 Subject: [PATCH 5/5] chore(plotnine): update quality score 83 and review feedback for line-stress-strain --- .../implementations/python/plotnine.py | 4 +- .../metadata/python/plotnine.yaml | 219 +++++++++--------- 2 files changed, 108 insertions(+), 115 deletions(-) diff --git a/plots/line-stress-strain/implementations/python/plotnine.py b/plots/line-stress-strain/implementations/python/plotnine.py index 395ce128a2..a8b182f85e 100644 --- a/plots/line-stress-strain/implementations/python/plotnine.py +++ b/plots/line-stress-strain/implementations/python/plotnine.py @@ -1,7 +1,7 @@ -"""anyplot.ai +""" anyplot.ai line-stress-strain: Engineering Stress-Strain Curve Library: plotnine 0.15.7 | Python 3.13.14 -Quality: 79/100 | Updated: 2026-06-21 +Quality: 83/100 | Updated: 2026-06-21 """ import os diff --git a/plots/line-stress-strain/metadata/python/plotnine.yaml b/plots/line-stress-strain/metadata/python/plotnine.yaml index e44c441a39..6d5b8a38eb 100644 --- a/plots/line-stress-strain/metadata/python/plotnine.yaml +++ b/plots/line-stress-strain/metadata/python/plotnine.yaml @@ -2,7 +2,7 @@ library: plotnine language: python specification_id: line-stress-strain created: '2026-03-20T21:22:28Z' -updated: '2026-06-21T09:47:49Z' +updated: '2026-06-21T09:58:32Z' generated_by: claude-sonnet workflow_run: 27900085743 issue: 4413 @@ -12,65 +12,48 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/line-stre preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/line-stress-strain/python/plotnine/plot-dark.png preview_html_light: null preview_html_dark: null -quality_score: 79 +quality_score: 83 review: strengths: - - 'Complete spec compliance: all required features implemented — elastic/strain-hardening/necking - region bands, yield point with 0.2% offset construction line, UTS marker, fracture - point, and elastic modulus annotation' - - 'Perfect data quality: realistic mild steel parameters (E=210 GPa, yield=250 MPa, - UTS=400 MPa, fracture_strain=0.35) with correct power-law hardening and necking - profile' - - 'Correct Imprint palette usage: first series (main curve) in #009E73 brand green; - region shading uses Imprint palette positions 2-4 with alpha blending; critical - point markers use semantic matte red #AE3030' - - 'Full theme-adaptive chrome: PAGE_BG, INK, INK_SOFT tokens correctly applied to - all non-data elements; both renders use correct backgrounds (#FAF8F1 light / #1A1A17 - dark)' - - 'Perfect code quality: KISS flat script, np.random.seed(42) for reproducibility, - only used imports, clean plotnine grammar-of-graphics layering' + - 'Correct Imprint palette usage with #009E73 as main curve, theme-adaptive chrome + in both renders' + - 'Complete spec compliance: region shading, 0.2% offset line, all critical points + (yield, UTS, fracture) annotated, elastic modulus labeled' + - 'Accurate engineering data: E=210 GPa for mild steel, plausible yield/UTS/fracture + values' + - Clean plotnine grammar of graphics layering with annotate rect regions and geom_segment + for offset line + - KISS code structure with explicit sys.path workaround for naming conflict properly + handled + - Both light and dark renders are readable with no dark-on-dark text failures weaknesses: - - 'SC-04 FAIL: Title reads ''line-stress-strain · plotnine · pyplots.ai'' but must - be ''line-stress-strain · python · plotnine · anyplot.ai''. Two issues: (1) ''python'' - language is missing between library and domain; (2) domain is ''pyplots.ai'' instead - of ''anyplot.ai''. Fix: labs(title=''line-stress-strain · python · plotnine · - anyplot.ai'')' - - '''Elastic'' region label (x=0.003) is positioned inside the strain-hardening - band, not the elastic region, because the elastic zone ends at ~0.00119 strain. - The label is confusingly outside its region. Fix: place label inside the narrow - elastic band (x≈0.0005, y=200) or use a small horizontal arrow/segment to connect - it' - - 'In the dark render, the ''Elastic'' region band (IMPRINT[2] #4467A3 with alpha=0.28 - on #1A1A17) creates a dark olive fill that significantly reduces chart area contrast. - The three overlapping alpha-blended bands in dark mode produce heavy, saturated - fills that compete with the data curve. Consider reducing REGION_ALPHA to 0.12-0.15 - for dark theme for a more refined look' - - Four-sided panel border (panel_border=element_rect) is kept instead of the style-guide's - recommended L-shaped frame (remove top and right spines). For an engineering chart - this is defensible, but removing top/right spines would improve visual refinement - - The '0.2% offset' italic annotation (size=3.0mm, color=IMPRINT[4]) at y=52 is - very small and in matte red (#AE3030) against the dark olive region background - in the dark render — marginally legible. Increase to size=3.5 and consider using - INK_SOFT for better contrast on both themes - - 'CVD concern: the main curve (#009E73 green) and the critical-point markers (#AE3030 - red) form a green-red pair. While they encode different chart roles (line vs. - markers), deuteranopia users may have difficulty distinguishing them. The markers - already use distinct shape (filled circle), which partially mitigates this' + - Secondary annotation texts (region labels, critical point annotations) use size=3.0 + in geom_text (≈8.5pt), which are barely readable at 400px mobile width — consider + size=3.5–4.0 for these labels + - Full 4-sided panel border retained via panel_border=element_rect(...); style guide + recommends L-shaped frame (remove top/right spines) — would improve minimalism + and visual refinement + - DE-01 aesthetic sophistication is limited to spec-required elements; no additional + design choices like refined line weights, font weight hierarchy for annotations, + or intentional whitespace around key features + - LM-02 library distinctiveness is modest — annotate rect regions are idiomatic + ggplot2/plotnine but not uniquely leveraging plotnine capabilities beyond what + ggplot2 could do identically image_description: |- Light render (plot-light.png): - Background: Warm off-white #FAF8F1 — correct per style guide. Not pure white. - Chrome: Title "line-stress-strain · plotnine · pyplots.ai" bold black, clearly readable. Axis labels "Engineering Strain" (x) and "Engineering Stress (MPa)" (y) in dark bold text, fully readable. Tick labels (0.00–0.35 on x, 0–450 on y) in dark soft color, readable. Y-axis-only horizontal grid lines are subtle and non-competing. - Data: Three colored region bands visible — a very narrow blue-tinted elastic sliver on the far left (~0 to 0.001), a beige/tan strain-hardening band (~0.001 to 0.22), and a pink/salmon necking band (0.22–0.35). Main stress-strain curve in brand green #009E73 is prominent and well-rendered with correct S-shape (elastic rise, yield plateau, strain hardening, necking). Three matte-red markers (#AE3030) at yield point (~0.003, 250 MPa), UTS (~0.22, 400 MPa), and fracture (~0.35, 320 MPa). Red dashed offset line is a nearly vertical sliver near origin. Annotations: "Yield Point (0.2% offset)" bold dark text, "UTS" bold above UTS marker, "Fracture" bold near fracture, "E = 210 GPa" in blue in lower-left, "0.2% offset" small italic red near bottom, region labels "Elastic"/"Strain\nHardening"/"Necking" in soft italic. - Legibility verdict: PASS — all text readable; "0.2% offset" is small but visible; "Elastic" label is positioned just outside the elastic region band. + Background: Warm off-white #FAF8F1 — clearly not pure white, matches the required surface. + Chrome: Title "line-stress-strain · python · plotnine · anyplot.ai" at bold 12pt is readable; Y-axis label "Engineering Stress (MPa)" and X-axis label "Engineering Strain" at 10pt are clear; tick labels at 8pt are readable. Horizontal grid only, subtle at alpha=0.15. Full 4-sided panel border in INK_SOFT. + Data: Main stress-strain curve in #009E73 (Imprint position 1 / brand green) — clearly visible. Three region shadings: elastic (blue #4467A3, very narrow left strip), strain hardening (ochre #BD8233, large middle region), necking (red #AE3030, right region). Critical point markers as red (#AE3030) dots at yield, UTS, fracture. Dashed red offset line at 0.2% offset. Blue text "E = 210 GPa" annotation. Region labels ("Elastic", "Strain Hardening", "Necking") in italic INK_SOFT. Critical point labels ("Yield Point (0.2% offset)", "UTS", "Fracture") in bold INK. + Legibility verdict: PASS for desktop. At 400px mobile width, secondary annotation texts (size=3.0 in geom_text ≈8.5pt) become barely readable — region labels and critical point labels are very small at mobile scale. Main axis labels and title remain readable. Dark render (plot-dark.png): - Background: Warm near-black #1A1A17 — correct per style guide. Not pure black. - Chrome: Title "line-stress-strain · plotnine · pyplots.ai" in bold light-cream text, clearly readable against dark background. Axis labels in adaptive light text, readable. Tick labels in soft light color (#B8B7B0 INK_SOFT), readable. Horizontal grid lines are subtle light lines, non-competing. No dark-on-dark failures for chrome elements. - Data: The three region bands produce notably heavier fills on dark — the elastic zone becomes a dark olive-blue tint, strain hardening becomes a dark olive-tan, and necking becomes a dark brownish-red. These fills are more saturated than in the light render. The green curve (#009E73) remains clearly visible as it contrasts well against all three dark band fills. The three matte-red markers remain identifiable. The "Yield Point (0.2% offset)" label appears in light cream (INK token), readable. "0.2% offset" italic red text at the bottom-left is marginally legible against the dark olive background — the matte red (#AE3030) has adequate but not generous contrast on #1A1A17. Data colors (green curve, red markers, colored bands) are identical to the light render — only chrome flips. - Legibility verdict: PASS (marginal) — all primary text is readable; "0.2% offset" italic annotation is the weakest legibility element on dark due to small size and matte red on dark background. + Background: Warm near-black #1A1A17 — correct dark surface, not pure black. + Chrome: Title, axis labels, and tick labels all render in light INK (#F0EFE8 / #B8B7B0) — clearly readable against the dark background. Horizontal grid subtle (alpha=0.15 in light INK). Full panel border in INK_SOFT. No dark-on-dark text failures — all labels use the theme-adaptive INK and INK_SOFT tokens correctly. + Data: Main curve remains #009E73 (identical to light render). Region shadings identical hues (alpha=0.13 for dark, slightly lower than light's 0.18). Critical point markers and offset line retain the same colors. All data colors are theme-independent as required. + Legibility verdict: PASS. All primary text readable; secondary annotation texts small but no worse than light render. Brand green curve visible and distinct. criteria_checklist: visual_quality: - score: 24 + score: 25 max: 30 items: - id: VQ-01 @@ -78,55 +61,61 @@ review: score: 6 max: 8 passed: true - comment: Title, axis labels, tick labels all readable in both themes. '0.2% - offset' annotation (size=3mm, matte red) is marginally legible in dark render. - 'Elastic' region label slightly mispositioned (in wrong band). Dock 2pts. + comment: Font sizes explicitly set (title=12, axis=10, ticks=8); all main + text readable at desktop. Secondary geom_text annotations at size=3.0mm + (≈8.5pt) are very small at 400px mobile width — region labels and critical + point labels borderline unreadable at small scale. - id: VQ-02 name: No Overlap score: 5 max: 6 passed: true - comment: Minor crowding near yield region where offset line, yield marker, - and 'Yield Point' label are close together. No hard overlap but tight. + comment: No actual text overlaps. The left elastic region area (x=0 to 0.03) + is dense with the dashed line, yield point marker, and multiple annotation + labels at different y positions, creating a crowded but non-overlapping + layout. - id: VQ-03 name: Element Visibility score: 5 max: 6 passed: true - comment: Green curve and red markers clearly visible. Elastic region band - is a very narrow sliver that's hard to distinguish from the left axis border. - Region bands heavier in dark mode. + comment: Main curve and critical point markers are clearly visible. Region + shadings are appropriately subtle. Elastic region shading is inherently + narrow (0 to 0.001 strain = <0.3% of x-axis) but this is accurate to engineering + reality. - id: VQ-04 name: Color Accessibility - score: 1 + score: 2 max: 2 passed: true - comment: Green curve + red markers create a CVD-challenging pair. Shape differentiation - (line vs. dot) partially mitigates but remains a concern for deuteranopia - users. + comment: Imprint palette is CVD-safe. Critical points use semantic red (#AE3030) + for failure markers. Region colors use blue, ochre, and red — distinguishable + under deuteranopia/protanopia. - id: VQ-05 name: Layout & Canvas score: 3 max: 4 passed: true - comment: Canvas gate passed. Good proportions overall. Elastic region very - narrow but inherent to stress-strain physics. No overflow/clipping. + comment: 'Canvas is 3200x1800 (8x4.5in at 400dpi) — correct landscape format. + Margins are balanced. Minor concern: full 4-sided panel border and some + density in the left region. No text clipping or overflow.' - id: VQ-06 name: Axis Labels & Title score: 2 max: 2 passed: true - comment: 'X: ''Engineering Strain'' (dimensionless — correct no units), Y: - ''Engineering Stress (MPa)'' with units. Clear and descriptive.' + comment: 'Y-axis: ''Engineering Stress (MPa)'' with units. X-axis: ''Engineering + Strain'' (dimensionless, no unit needed). Title format correct: ''line-stress-strain + · python · plotnine · anyplot.ai''.' - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: 'First series (main curve) = #009E73 brand green. Region shading - uses Imprint positions 2-4 with alpha. Critical markers use semantic matte - red #AE3030. Backgrounds #FAF8F1 light / #1A1A17 dark. Data colors identical - across themes.' + comment: 'First series (main curve) is #009E73 (brand green). Region shadings + use Imprint positions 3/4/5. Critical points use semantic red (#AE3030) + for fracture/failure markers. Backgrounds: #FAF8F1 light / #1A1A17 dark. + All chrome tokens are theme-adaptive. Data colors identical between themes.' design_excellence: score: 12 max: 20 @@ -136,27 +125,28 @@ review: score: 5 max: 8 passed: true - comment: 'Above default (4): thoughtful three-region color banding, multiple - annotation types, custom Imprint palette applied consistently. Below exceptional - due to heavy dark-mode region fills and no typography variations.' + comment: 'Above typical defaults: region shading with alpha, semantic color + choices, intentional annotation hierarchy. Not publication-ready exceptional + — limited beyond spec-required elements.' - id: DE-02 name: Visual Refinement score: 3 max: 6 passed: true - comment: theme_minimal base, vertical grid disabled, minor grid only. However - panel_border keeps 4-sided border instead of L-shaped frame per style guide. - Above default (2) for horizontal-only grid. + comment: Grid is horizontal-only and subtle (good). Panel border uses full + 4-sided frame (element_rect) instead of recommended L-shaped frame. Some + refinement visible but not fully minimal. - id: DE-03 name: Data Storytelling score: 4 max: 6 passed: true - comment: 'Strong storytelling: region bands, critical point annotations, 0.2% - offset construction, E modulus annotation all guide the viewer through the - material science narrative. Above default (2).' + comment: 'Strong storytelling: region shading guides viewer through material + behavior progression, labeled critical points tell the engineering story, + 0.2% offset method illustrated. Viewer immediately understands the plot''s + narrative.' spec_compliance: - score: 12 + score: 15 max: 15 items: - id: SC-01 @@ -164,31 +154,32 @@ review: score: 5 max: 5 passed: true - comment: Correct engineering stress-strain line chart with all characteristic + comment: Correct engineering stress-strain line plot with all major curve regions. - id: SC-02 name: Required Features score: 4 max: 4 passed: true - comment: 'All features present: region labels (elastic/strain hardening/necking), - yield point with 0.2% offset line, UTS marker, fracture point, E modulus - annotation.' + comment: 'All spec requirements met: region labels (elastic/strain hardening/necking), + critical points marked (yield/UTS/fracture), elastic modulus annotated (''E + = 210 GPa''), 0.2% offset line drawn. Multi-material overlay optional per + spec — not implemented, not penalized.' - id: SC-03 name: Data Mapping score: 3 max: 3 passed: true - comment: 'Correct: strain 0-0.35 on x, stress 0-400+ MPa on y, correct curve - shape with yield plateau and necking.' + comment: X=engineering strain (0-0.35), Y=engineering stress (0-460 MPa). + All data regions visible. - id: SC-04 name: Title & Legend - score: 0 + score: 3 max: 3 - passed: false - comment: 'FAIL: Title is ''line-stress-strain · plotnine · pyplots.ai''. Required - format is ''line-stress-strain · python · plotnine · anyplot.ai''. Two errors: - missing ''python'' language, wrong domain ''pyplots.ai'' vs ''anyplot.ai''.' + passed: true + comment: Title is 'line-stress-strain · python · plotnine · anyplot.ai' — + correct mandatory format. No legend (single main curve + region labels in + text annotations). data_quality: score: 15 max: 15 @@ -198,23 +189,23 @@ review: score: 6 max: 6 passed: true - comment: 'All aspects shown: elastic, yield plateau, strain hardening, necking, - fracture. 0.2% offset construction, modulus, critical points all present.' + comment: 'Shows all stages: elastic (linear), yield plateau, strain hardening + (power law), necking, fracture. 0.2% offset method correctly implemented + with proper slope.' - id: DQ-02 name: Realistic Context score: 5 max: 5 passed: true - comment: 'Mild steel parameters are textbook-accurate: E=210 GPa, yield=250 - MPa, UTS=400 MPa, fracture_strain=0.35. Neutral engineering context, no - controversial content.' + comment: Mild steel tensile test — real engineering scenario. Neutral, scientific + topic. - id: DQ-03 name: Appropriate Scale score: 4 max: 4 passed: true - comment: 175 data points provides smooth curves. Strain 0-0.35 and stress - 0-460 MPa axes appropriate for mild steel. Tick intervals sensible. + comment: E=210 GPa (correct for steel), yield=250 MPa, UTS=400 MPa, fracture + at 35% strain — all factually accurate for mild steel. code_quality: score: 10 max: 10 @@ -224,33 +215,34 @@ review: score: 3 max: 3 passed: true - comment: Flat linear script, no functions or classes. Clear variable organization. + comment: Clean Imports→Data→Plot→Save structure. sys.path manipulation is + a documented workaround for naming conflict, not over-engineering. - id: CQ-02 name: Reproducibility score: 2 max: 2 passed: true - comment: np.random.seed(42) set. Data is deterministic. + comment: np.random.seed(42) set. Data is largely deterministic from physics + equations. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports used. sys.path manipulation necessary for plotnine.py - filename conflict. + comment: All imports used. plotnine imports are comprehensive and all used + in the plot. - id: CQ-04 name: Code Elegance score: 2 max: 2 passed: true - comment: Clean plotnine grammar-of-graphics layering. No fake UI. Appropriate - complexity for the annotation density required. + comment: Clean, well-organized code. No fake UI or over-engineering. - id: CQ-05 name: Output & API score: 1 max: 1 passed: true - comment: Saves as plot-{THEME}.png with correct dpi=400, width=8, height=4.5. + comment: Saves as plot-{THEME}.png using current plotnine API. library_mastery: score: 6 max: 10 @@ -260,17 +252,17 @@ review: score: 4 max: 5 passed: true - comment: 'Good idiomatic plotnine: annotate() for non-data shapes, geom_segment() - for line segments, scale_color_identity() + scale_size_identity() for manual - aesthetics, coord_cartesian() for axis limits. Above default (3).' + comment: 'Good grammar of graphics approach: annotate+geom_line+geom_point+geom_segment+geom_text + layers. Uses scale_color_identity and scale_size_identity idiomatically. + coord_cartesian for axis limits is correct ggplot2 pattern.' - id: LM-02 name: Distinctive Features score: 2 max: 5 - passed: true - comment: Uses annotate('rect') for region shading (ggplot2-specific), geom_text() - for vectorized labels, grammar-of-graphics layering. Above default (1) but - no advanced plotnine-specific features like faceting or complex scales. + passed: false + comment: annotate('rect', ...) for region shading is idiomatic ggplot2/plotnine. + Otherwise could be reproduced in matplotlib with similar effort. No uniquely + plotnine-exclusive feature exploited. verdict: APPROVED impl_tags: dependencies: [] @@ -283,3 +275,4 @@ impl_tags: dataprep: [] styling: - alpha-blending + - grid-styling