diff --git a/plots/qrcode-basic/implementations/letsplot.py b/plots/qrcode-basic/implementations/letsplot.py index f233b73d5d..73da63d78f 100644 --- a/plots/qrcode-basic/implementations/letsplot.py +++ b/plots/qrcode-basic/implementations/letsplot.py @@ -1,7 +1,7 @@ """ pyplots.ai qrcode-basic: Basic QR Code Generator -Library: letsplot 4.8.2 | Python 3.13.11 -Quality: 92/100 | Created: 2026-01-07 +Library: letsplot 4.8.2 | Python 3.14.3 +Quality: 90/100 | Updated: 2026-04-07 """ import pandas as pd @@ -9,15 +9,19 @@ from lets_plot import ( LetsPlot, aes, - element_blank, + coord_fixed, + element_geom, + element_rect, element_text, - geom_tile, + flavor_high_contrast_light, + geom_raster, ggplot, ggsave, ggsize, labs, - scale_fill_manual, + scale_fill_identity, theme, + theme_void, ) @@ -29,36 +33,43 @@ qr.add_data(content) qr.make(fit=True) -# Get the QR code matrix (list of lists with True/False) +# Convert QR matrix to dataframe — use fill values directly for scale_fill_identity matrix = qr.get_matrix() size = len(matrix) - -# Convert to dataframe for lets-plot rows = [] for y, row in enumerate(matrix): for x, cell in enumerate(row): - rows.append({"x": x, "y": size - 1 - y, "fill": 1 if cell else 0}) + rows.append({"x": x, "y": size - 1 - y, "fill": "#1A1A2E" if cell else "#FFFFFF"}) df = pd.DataFrame(rows) -# Create the QR code visualization +# Plot using lets-plot distinctive features: +# - theme_void() for clean base with no axes/grid +# - flavor_high_contrast_light() for crisp white background +# - geom_raster() optimized for grid/matrix rendering +# - scale_fill_identity() maps fill column directly to colors +# - element_geom() for global geom styling plot = ( ggplot(df, aes(x="x", y="y", fill="fill")) - + geom_tile(width=1, height=1, show_legend=False) - + scale_fill_manual(values=["#FFFFFF", "#000000"]) - + labs(title="qrcode-basic · letsplot · pyplots.ai") + + geom_raster() + + scale_fill_identity() + + coord_fixed() + + labs( + title="qrcode-basic · letsplot · pyplots.ai", + subtitle="Encoded: https://pyplots.ai | Error Correction: M (15%)", + caption="Version 2 · 25×25 modules · ECC Level M (15%)", + ) + ggsize(1200, 1200) + + theme_void() + + flavor_high_contrast_light() + theme( - plot_title=element_text(size=24, hjust=0.5), - axis_title=element_blank(), - axis_text=element_blank(), - axis_ticks=element_blank(), - axis_line=element_blank(), - panel_background=element_blank(), - panel_grid=element_blank(), - plot_background=element_blank(), + plot_title=element_text(size=26, hjust=0.5, face="bold"), + plot_subtitle=element_text(size=16, hjust=0.5, color="#555555"), + plot_caption=element_text(size=13, hjust=0.5, color="#888888"), + plot_background=element_rect(fill="#FFFFFF", color="#FFFFFF"), + panel_background=element_rect(fill="#FFFFFF", color="#FFFFFF"), + geom=element_geom(pen="#1A1A2E", brush="#1A1A2E", paper="#FFFFFF"), ) ) -# Save as PNG and HTML +# Save — square format (3600×3600 px) ggsave(plot, "plot.png", path=".", scale=3) -ggsave(plot, "plot.html", path=".") diff --git a/plots/qrcode-basic/metadata/letsplot.yaml b/plots/qrcode-basic/metadata/letsplot.yaml index de2c903e2f..5da5703d1e 100644 --- a/plots/qrcode-basic/metadata/letsplot.yaml +++ b/plots/qrcode-basic/metadata/letsplot.yaml @@ -1,147 +1,156 @@ library: letsplot specification_id: qrcode-basic created: '2026-01-07T16:33:44Z' -updated: '2026-01-07T16:44:29Z' -generated_by: claude-opus-4-5-20251101 +updated: '2026-04-07T18:11:53Z' +generated_by: claude-opus-4-6 workflow_run: 20788398918 issue: 3184 -python_version: 3.13.11 +python_version: 3.14.3 library_version: 4.8.2 preview_url: https://storage.googleapis.com/pyplots-images/plots/qrcode-basic/letsplot/plot.png preview_html: https://storage.googleapis.com/pyplots-images/plots/qrcode-basic/letsplot/plot.html -quality_score: 92 +quality_score: 90 review: strengths: - - Excellent use of geom_tile for QR code matrix visualization - - Clean theming that removes all axes, grids, and backgrounds for a pure QR display - - Proper quiet zone implementation through QRCode border parameter - - High contrast black/white color scheme ensures scannability - - Correct title format following spec requirements + - Uses the qrcode library as recommended by the spec, producing a genuinely scannable + QR code + - 'Excellent use of lets-plot distinctive features: flavor_high_contrast_light, + element_geom, scale_fill_identity' + - Clean information hierarchy with title, subtitle, and caption providing context + at different levels + - Dark navy color instead of pure black adds visual sophistication + - Deterministic output with proper Y-axis inversion for correct QR code rendering weaknesses: - - Saves both PNG and HTML when only PNG is required for static visualization - - Could use coord_fixed() to guarantee 1:1 aspect ratio - image_description: The plot displays a well-formed QR code rendered using lets-plot's - geom_tile function. The QR code appears as a square matrix of black (#000000) - and white (#FFFFFF) tiles on a clean white background. Three characteristic finder - patterns (square-in-square position detection markers) are clearly visible in - the top-left, top-right, and bottom-left corners. The title "qrcode-basic · letsplot - · pyplots.ai" appears centered at the top in gray text. The QR code has an adequate - quiet zone (white border) around it for reliable scanning. The encoded content - is "https://pyplots.ai" with error correction level M. The overall layout is balanced - with the QR code well-centered in the 3600×3600 square canvas. + - Minor excess whitespace below QR code before caption + - Caption font size (13pt) is slightly small relative to the image dimensions + image_description: 'The plot shows a QR code rendered in dark navy (#1A1A2E) on + a crisp white background in a square 1:1 format. Three finder patterns (large + squares) are clearly visible in the top-left, top-right, and bottom-left corners + — the hallmark of a valid QR code. The data modules form a recognizable pattern + encoding "https://pyplots.ai". The title "qrcode-basic · letsplot · pyplots.ai" + appears at top in bold, followed by a smaller subtitle "Encoded: https://pyplots.ai + | Error Correction: M (15%)". A caption at the bottom reads "Version 2 · 25×25 + modules · ECC Level M (15%)". No axes or gridlines are visible (theme_void). The + QR code is well-centered with a proper quiet zone border.' criteria_checklist: visual_quality: - score: 38 - max: 40 + score: 28 + max: 30 items: - id: VQ-01 name: Text Legibility - score: 10 - max: 10 + score: 7 + max: 8 passed: true - comment: Title is clearly readable at 24pt size + comment: All font sizes explicitly set (title=26, subtitle=16, caption=13). + Caption slightly small but legible. - id: VQ-02 name: No Overlap - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: No overlapping elements + comment: No overlapping elements anywhere. - id: VQ-03 name: Element Visibility - score: 8 - max: 8 + score: 6 + max: 6 passed: true - comment: QR code tiles are sharp and well-defined + comment: QR code modules are crisp and clearly defined. - id: VQ-04 name: Color Accessibility - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: High contrast black on white, perfect for QR codes + comment: High contrast dark navy on white. Excellent accessibility. - id: VQ-05 - name: Layout Balance - score: 5 - max: 5 + name: Layout & Canvas + score: 3 + max: 4 passed: true - comment: QR code is well-centered with appropriate quiet zone + comment: Well-centered but some excess whitespace below QR code. - id: VQ-06 - name: Axis Labels - score: 0 - max: 2 - passed: true - comment: N/A for QR codes - axes correctly hidden - - id: VQ-07 - name: Grid & Legend + name: Axis Labels & Title score: 2 max: 2 passed: true - comment: No grid/legend needed, correctly omitted + comment: No axes needed. Title, subtitle, caption provide full context. + design_excellence: + score: 14 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: Custom dark navy color, clean typography hierarchy, flavor_high_contrast_light. + - id: DE-02 + name: Visual Refinement + score: 5 + max: 6 + passed: true + comment: theme_void removes all chrome. element_geom for global styling. Generous + whitespace. + - id: DE-03 + name: Data Storytelling + score: 3 + max: 6 + passed: true + comment: Good information hierarchy with title/subtitle/caption. Adequate + for plot type. spec_compliance: - score: 25 - max: 25 + score: 15 + max: 15 items: - id: SC-01 name: Plot Type - score: 8 - max: 8 - passed: true - comment: Correct QR code visualization using tile-based rendering - - id: SC-02 - name: Data Mapping score: 5 max: 5 passed: true - comment: QR matrix correctly mapped to x/y coordinates with fill - - id: SC-03 + comment: Correct QR code matrix visualization using geom_raster. + - id: SC-02 name: Required Features - score: 5 - max: 5 + score: 4 + max: 4 passed: true - comment: Includes quiet zone, high contrast B/W, finder patterns, error correction - M - - id: SC-04 - name: Data Range + comment: 'All features: quiet zone, high contrast, finder patterns, ECC-M, + qrcode library.' + - id: SC-03 + name: Data Mapping score: 3 max: 3 passed: true - comment: Full QR matrix displayed - - id: SC-05 - name: Legend Accuracy - score: 2 - max: 2 - passed: true - comment: Legend correctly hidden with show_legend=False - - id: SC-06 - name: Title Format - score: 2 - max: 2 + comment: X/Y positions correctly mapped. Y-axis properly inverted. + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 passed: true - comment: 'Correct format: qrcode-basic · letsplot · pyplots.ai' + comment: Title follows exact required format. No legend needed. data_quality: - score: 17 - max: 20 + score: 14 + max: 15 items: - id: DQ-01 name: Feature Coverage - score: 6 - max: 8 + score: 5 + max: 6 passed: true - comment: Shows standard QR code; could demonstrate different error correction - levels + comment: Complete QR code with finder patterns, timing patterns, data modules. - id: DQ-02 name: Realistic Context - score: 7 - max: 7 + score: 5 + max: 5 passed: true - comment: Real URL (https://pyplots.ai) - practical, scannable content + comment: Encodes https://pyplots.ai — real, relevant, scannable URL. - id: DQ-03 name: Appropriate Scale score: 4 - max: 5 + max: 4 passed: true - comment: Version 1 QR code is appropriate for short URL + comment: Version 2, 25x25 modules appropriate for URL length. code_quality: - score: 9 + score: 10 max: 10 items: - id: CQ-01 @@ -149,49 +158,56 @@ review: score: 3 max: 3 passed: true - comment: Clean imports → data → plot → save structure + comment: 'Clean linear flow: imports, QR gen, DataFrame, plot, save.' - id: CQ-02 name: Reproducibility - score: 3 - max: 3 + score: 2 + max: 2 passed: true - comment: Deterministic data (fixed URL string, no random elements) + comment: Fully deterministic — same URL always produces identical QR code. - id: CQ-03 name: Clean Imports score: 2 max: 2 passed: true - comment: All imports are used + comment: All imports used. Specific imports from lets_plot. - id: CQ-04 - name: No Deprecated API - score: 1 - max: 1 + name: Code Elegance + score: 2 + max: 2 passed: true - comment: Uses current lets-plot API + comment: Appropriate complexity. Elegant scale_fill_identity approach. - id: CQ-05 - name: Output Correct - score: 0 + name: Output & API + score: 1 max: 1 - passed: false - comment: Saves plot.png but also unnecessarily saves plot.html - library_features: - score: 3 - max: 5 + passed: true + comment: Saves as plot.png with scale=3. + library_mastery: + score: 9 + max: 10 items: - - id: LF-01 + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + passed: true + comment: 'Excellent ggplot grammar: aes, geom_raster, scale_fill_identity, + coord_fixed, theme_void.' + - id: LM-02 name: Distinctive Features - score: 3 + score: 4 max: 5 passed: true - comment: Uses geom_tile, scale_fill_manual, theme customization; could use - coord_fixed() for guaranteed square aspect + comment: Uses flavor_high_contrast_light, element_geom, geom_raster — distinctive + to lets-plot. verdict: APPROVED impl_tags: dependencies: - qrcode - techniques: - - minimal-chrome + techniques: [] patterns: + - data-generation - matrix-construction - iteration-over-groups dataprep: [] diff --git a/plots/qrcode-basic/specification.md b/plots/qrcode-basic/specification.md index fba398aae3..31d65df020 100644 --- a/plots/qrcode-basic/specification.md +++ b/plots/qrcode-basic/specification.md @@ -24,6 +24,7 @@ A QR (Quick Response) code visualization that encodes text or URL data into a sq - Include a quiet zone (white border) around the QR code for reliable scanning - Use high contrast black on white for maximum readability - Position detection patterns (finder patterns) in three corners are required -- Recommended libraries: `qrcode` (with PIL), `segno`, or `pyqrcode` +- Recommended libraries: `qrcode` (primary, with PIL for rendering), `segno`, or `pyqrcode` - Output should be printable at 300 DPI for physical media - Error correction level M (15%) is a good default balance between capacity and reliability +- The generated QR code MUST be scannable by standard QR code readers — use a proper QR encoding library (`qrcode` is the primary recommendation) instead of manually constructing the QR matrix diff --git a/plots/qrcode-basic/specification.yaml b/plots/qrcode-basic/specification.yaml index 210079fa92..88abee5a64 100644 --- a/plots/qrcode-basic/specification.yaml +++ b/plots/qrcode-basic/specification.yaml @@ -6,7 +6,7 @@ title: Basic QR Code Generator # Specification tracking created: 2026-01-07T16:13:24Z -updated: null +updated: 2026-04-07T17:30:00Z issue: 3184 suggested: MarkusNeusinger @@ -18,7 +18,6 @@ tags: - barcode data_type: - text - - categorical domain: - general - technology