diff --git a/plots/acf-pacf/implementations/python/pygal.py b/plots/acf-pacf/implementations/python/pygal.py
index 5582e97374..7659c45a04 100644
--- a/plots/acf-pacf/implementations/python/pygal.py
+++ b/plots/acf-pacf/implementations/python/pygal.py
@@ -1,9 +1,18 @@
-""" pyplots.ai
+""" anyplot.ai
acf-pacf: Autocorrelation and Partial Autocorrelation (ACF/PACF) Plot
-Library: pygal 3.1.0 | Python 3.14.3
-Quality: 85/100 | Created: 2026-03-14
+Library: pygal 3.1.0 | Python 3.13.13
+Quality: 85/100 | Updated: 2026-06-10
"""
+import os
+import sys
+
+
+# Remove this file's directory from sys.path so `import pygal` resolves to the
+# installed package, not this script (which shares the same name).
+_this_dir = os.path.dirname(os.path.abspath(__file__))
+sys.path = [p for p in sys.path if os.path.abspath(p or ".") != _this_dir]
+
import io
import xml.etree.ElementTree as ET
@@ -15,7 +24,29 @@
from statsmodels.tsa.stattools import acf, pacf
-# Data - Synthetic monthly airline-style passenger data with trend and seasonality
+# Theme-adaptive tokens (Imprint palette)
+THEME = os.getenv("ANYPLOT_THEME", "light")
+PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
+INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
+INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
+
+# Imprint categorical palette — canonical order, theme-independent
+IMPRINT_PALETTE = ("#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477", "#99B314")
+ANYPLOT_AMBER = "#DDCC77" # significance threshold lines (caution/warning role)
+
+# Semantic color roles for this chart
+HIGHLIGHT_COLOR = IMPRINT_PALETTE[0] # #009E73 — significant bars (first series, always)
+MUTED_BAR_COLOR = INK_MUTED # non-significant bars
+CONF_LINE_COLOR = ANYPLOT_AMBER # 95% CI threshold lines
+ZERO_LINE_COLOR = INK_MUTED # zero baseline
+
+
+def hex_to_rgb(hex_str):
+ h = hex_str.lstrip("#")
+ return tuple(int(h[i : i + 2], 16) for i in (0, 2, 4))
+
+
+# Data — synthetic monthly airline-style passenger data with trend and seasonality
np.random.seed(42)
n_obs = 200
t = np.arange(n_obs)
@@ -24,96 +55,94 @@
noise = np.random.normal(0, 2, n_obs)
passengers = 100 + trend + seasonal + noise
-# Compute ACF and PACF
+# ACF/PACF computation
n_lags = 36
acf_values = acf(passengers, nlags=n_lags, fft=True)
pacf_values = pacf(passengers, nlags=n_lags, method="ywm")
conf_bound = 1.96 / np.sqrt(n_obs)
-# Color palette - refined for publication quality
-highlight_color = "#306998"
-muted_color = "#B8D4E8"
-conf_line_color = "#C0392B"
-bg_color = "#FAFAFA"
-text_color = "#1A1A2E"
-grid_color = "#E8ECF0"
-zero_line_color = "#95A5A6"
-
+# Style — Imprint palette, theme-adaptive chrome; canvas = 3200×1800 (two 3200×900 panels)
custom_style = Style(
- background="white",
- plot_background=bg_color,
- foreground=text_color,
- foreground_strong=text_color,
- foreground_subtle=grid_color,
- colors=(highlight_color,),
- title_font_size=48,
- label_font_size=30,
- major_label_font_size=30,
- legend_font_size=24,
- value_font_size=18,
+ background=PAGE_BG,
+ plot_background=PAGE_BG,
+ foreground=INK,
+ foreground_strong=INK,
+ foreground_subtle=INK_MUTED,
+ colors=IMPRINT_PALETTE,
+ title_font_size=66,
+ label_font_size=56,
+ major_label_font_size=44,
+ legend_font_size=44,
+ value_font_size=36,
+ stroke_width=2.5,
font_family="'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
title_font_family="'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
label_font_family="'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
value_font_family="'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
)
-# Y-axis ranges tailored to actual data with slight padding
+# Y-axis ranges tailored to data
acf_min, acf_max = -0.5, 1.1
pacf_min, pacf_max = -0.5, 1.0
-# Common chart config - high spacing for narrow stem-like bars
+# Each panel: 3200×900; two panels stacked → 3200×1800 landscape
common_config = {
- "width": 4800,
- "height": 1300,
+ "width": 3200,
+ "height": 900,
"style": custom_style,
"show_legend": False,
"show_y_guides": True,
"show_x_guides": False,
- "margin": 25,
- "margin_left": 120,
+ "margin": 20,
+ "margin_left": 130,
"margin_right": 60,
- "spacing": 100,
+ "spacing": 80,
"truncate_label": -1,
"print_values": False,
"show_minor_x_labels": False,
"x_labels_major_every": 4,
"rounded_bars": 2,
- "y_labels_major_count": 5,
}
-# ACF chart
+# ACF chart (top panel)
acf_chart = pygal.Bar(
**common_config,
x_title="",
y_title="ACF",
- title="acf-pacf · pygal · pyplots.ai",
+ title="acf-pacf · python · pygal · anyplot.ai",
margin_bottom=10,
margin_top=30,
range=(acf_min, acf_max),
)
acf_chart.x_labels = [str(i) for i in range(n_lags + 1)]
+acf_chart.y_labels = [-0.4, -0.2, 0.0, 0.5, 1.0]
acf_chart.add(
"ACF",
- [{"value": round(v, 4), "color": highlight_color if abs(v) > conf_bound else muted_color} for v in acf_values],
+ [{"value": round(v, 4), "color": HIGHLIGHT_COLOR if abs(v) > conf_bound else MUTED_BAR_COLOR} for v in acf_values],
)
-# PACF chart
+# PACF chart (bottom panel)
pacf_chart = pygal.Bar(
**common_config, x_title="Lag", y_title="PACF", title="", margin_bottom=70, margin_top=5, range=(pacf_min, pacf_max)
)
pacf_chart.x_labels = [str(i) for i in range(1, n_lags + 1)]
+pacf_chart.y_labels = [-0.4, -0.2, 0.0, 0.5, 1.0]
pacf_chart.add(
"PACF",
- [{"value": round(v, 4), "color": highlight_color if abs(v) > conf_bound else muted_color} for v in pacf_values[1:]],
+ [
+ {"value": round(v, 4), "color": HIGHLIGHT_COLOR if abs(v) > conf_bound else MUTED_BAR_COLOR}
+ for v in pacf_values[1:]
+ ],
)
-# Render SVGs and inject confidence lines (pygal lacks native reference lines)
+# SVG namespace registration
ns = "http://www.w3.org/2000/svg"
ET.register_namespace("", ns)
ET.register_namespace("xlink", "http://www.w3.org/1999/xlink")
-png_images = []
-for chart, y_min, y_max in [(acf_chart, acf_min, acf_max), (pacf_chart, pacf_min, pacf_max)]:
+
+def _inject_ci_lines(chart, y_min, y_max):
+ """Inject CI dashed lines and zero baseline into pygal's SVG (no native reference-line API)."""
root = ET.fromstring(chart.render())
plot_group = next((g for g in root.iter(f"{{{ns}}}g") if g.get("class", "") == "plot"), None)
if plot_group is not None:
@@ -121,6 +150,7 @@
if bg_rect is not None:
pw, ph = float(bg_rect.get("width")), float(bg_rect.get("height"))
y_range = y_max - y_min
+ # 95% CI bounds (dashed amber lines)
for cv in [conf_bound, -conf_bound]:
ly = (y_max - cv) / y_range * ph
line = ET.SubElement(plot_group, f"{{{ns}}}line")
@@ -128,60 +158,67 @@
line.set("y1", f"{ly:.1f}")
line.set("x2", str(pw))
line.set("y2", f"{ly:.1f}")
- line.set("stroke", conf_line_color)
+ line.set("stroke", CONF_LINE_COLOR)
line.set("stroke-width", "3")
line.set("stroke-dasharray", "18,10")
- line.set("opacity", "0.75")
- # Zero baseline emphasis
+ line.set("opacity", "0.9")
+ # Zero baseline (muted solid line)
zy = (y_max - 0) / y_range * ph
zline = ET.SubElement(plot_group, f"{{{ns}}}line")
zline.set("x1", "0")
zline.set("y1", f"{zy:.1f}")
zline.set("x2", str(pw))
zline.set("y2", f"{zy:.1f}")
- zline.set("stroke", zero_line_color)
+ zline.set("stroke", ZERO_LINE_COLOR)
zline.set("stroke-width", "2.5")
zline.set("opacity", "0.6")
+ return root
- png_images.append(cairosvg.svg2png(bytestring=ET.tostring(root), output_width=4800, output_height=1300))
-# Compose final image
-acf_img = Image.open(io.BytesIO(png_images[0]))
-pacf_img = Image.open(io.BytesIO(png_images[1]))
-combined = Image.new("RGB", (4800, 2700), "white")
-combined.paste(acf_img, (0, 50))
-combined.paste(pacf_img, (0, 1350))
-
-# Subtle divider line between charts
+# Render both panels
+panels = []
+svg_strings = []
+for chart, y_min, y_max in [(acf_chart, acf_min, acf_max), (pacf_chart, pacf_min, pacf_max)]:
+ root = _inject_ci_lines(chart, y_min, y_max)
+ svg_bytes = ET.tostring(root)
+ svg_strings.append(ET.tostring(root, encoding="unicode"))
+ png_data = cairosvg.svg2png(bytestring=svg_bytes, output_width=3200, output_height=900)
+ img = Image.open(io.BytesIO(png_data)).convert("RGB")
+ img = img.resize((3200, 900), Image.LANCZOS)
+ panels.append(img)
+
+# Compose 3200×1800 landscape canvas
+combined = Image.new("RGB", (3200, 1800), hex_to_rgb(PAGE_BG))
+combined.paste(panels[0], (0, 0))
+combined.paste(panels[1], (0, 900))
+
+# Subtle divider between panels
draw = ImageDraw.Draw(combined)
-draw.line([(120, 1350), (4740, 1350)], fill="#DEE2E6", width=2)
+draw.line([(130, 900), (3140, 900)], fill=hex_to_rgb(INK_MUTED), width=1)
-# Confidence bound annotation - positioned in upper-right margin area
+# CI annotation in upper-right margin
try:
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 30)
except OSError:
font = ImageFont.load_default()
-draw.text((4200, 68), f"95% CI: ±{conf_bound:.3f}", fill=conf_line_color, font=font)
-
-combined.save("plot.png", dpi=(300, 300))
+draw.text((2640, 24), f"95% CI: ±{conf_bound:.3f}", fill=CONF_LINE_COLOR, font=font)
-# HTML version with interactive SVGs
-acf_svg = acf_chart.render(is_unicode=True).replace('', "")
-pacf_svg = pacf_chart.render(is_unicode=True).replace('', "")
+combined.save(f"plot-{THEME}.png", dpi=(300, 300))
+# Interactive HTML output (pygal renders interactive SVG charts)
html_content = (
"\n\n
\n"
- " acf-pacf · pygal · pyplots.ai\n"
+ " acf-pacf · python · pygal · anyplot.ai\n"
" \n\n\n"
" \n"
- f"
{acf_svg}
\n"
- f"
{pacf_svg}
\n"
+ f"
{svg_strings[0]}
\n"
+ f"
{svg_strings[1]}
\n"
"
\n\n"
)
-with open("plot.html", "w") as f:
+with open(f"plot-{THEME}.html", "w") as f:
f.write(html_content)
diff --git a/plots/acf-pacf/metadata/python/pygal.yaml b/plots/acf-pacf/metadata/python/pygal.yaml
index 253adb0cb5..a20562c14a 100644
--- a/plots/acf-pacf/metadata/python/pygal.yaml
+++ b/plots/acf-pacf/metadata/python/pygal.yaml
@@ -1,44 +1,58 @@
library: pygal
+language: python
specification_id: acf-pacf
created: '2026-03-14T22:18:53Z'
-updated: '2026-03-14T22:56:02Z'
-generated_by: claude-opus-4-5-20251101
-workflow_run: 23097477625
+updated: '2026-06-10T02:04:01Z'
+generated_by: claude-sonnet
+workflow_run: 27247413374
issue: 4663
-python_version: 3.14.3
+language_version: 3.13.13
library_version: 3.1.0
-preview_url: https://storage.googleapis.com/anyplot-images/plots/acf-pacf/pygal/plot.png
-preview_html: https://storage.googleapis.com/anyplot-images/plots/acf-pacf/pygal/plot.html
+preview_url_light: https://storage.googleapis.com/anyplot-images/plots/acf-pacf/python/pygal/plot-light.png
+preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/acf-pacf/python/pygal/plot-dark.png
+preview_html_light: https://storage.googleapis.com/anyplot-images/plots/acf-pacf/python/pygal/plot-light.html
+preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/acf-pacf/python/pygal/plot-dark.html
quality_score: 85
review:
strengths:
- - Excellent data storytelling through color differentiation of significant vs non-significant
- lags
- - Creative SVG post-processing to inject confidence interval lines (overcoming pygal
- limitation)
- - Perfect data quality with classic airline-style seasonal time series
- - Clean dual-panel composition with shared x-axis concept
- - HTML export preserves pygal native interactive tooltips
+ - 'Semantic color coding (significant=green #009E73, non-significant=gray) provides
+ immediate interpretive value without a legend'
+ - ANYPLOT_AMBER (#DDCC77) used correctly as a warning/caution anchor for 95% CI
+ threshold lines
+ - 'Both renders fully theme-adaptive: backgrounds, text, and gridlines correctly
+ flip between light (#FAF8F1) and dark (#1A1A17) themes'
+ - SVG injection via ElementTree is an elegant workaround for pygal's missing reference-line
+ API, enabling dashed CI lines
+ - Data (airline-style seasonal series, n=200) produces textbook ACF/PACF patterns
+ showcasing the plot type effectively
+ - 'Clean code: shared common_config dict reduces repetition; per-bar color dict
+ is idiomatic pygal usage'
weaknesses:
- - Bars are wider than ideal stem lines, though this is a pygal limitation
- - Some wasted vertical space at bottom of canvas below Lag label
- - SVG manipulation code adds complexity that slightly reduces code elegance
- image_description: 'The plot displays two vertically stacked pygal bar charts on
- a light gray (#FAFAFA) background. The top chart shows ACF values from lag 0 to
- 36 with the title "acf-pacf · pygal · pyplots.ai" and y-axis labeled "ACF". The
- bottom chart shows PACF values from lag 1 to 36 with y-axis labeled "PACF" and
- x-axis labeled "Lag". Bars are colored in dark blue (#306998) when values exceed
- the 95% confidence bounds, and light blue (#B8D4E8) when within bounds. Red dashed
- horizontal lines at approximately ±0.139 indicate the 95% confidence interval.
- A gray zero baseline is visible in both charts. A red annotation "95% CI: ±0.139"
- appears in the upper-right corner. The ACF chart shows a clear sinusoidal decay
- pattern with peaks at lags 0, 12, 24, 36 (period-12 seasonality). The PACF chart
- shows a strong spike at lag 1 (~0.8), significant negative values at lags 2-4,
- positive spikes around lags 7-10, and mostly non-significant values beyond lag
- 12. A subtle gray divider separates the two charts.'
+ - Filled bars (pygal.Bar) instead of vertical stem lines — spec explicitly requires
+ 'vertical stem lines (not filled bars)'; consider very narrow bar widths or SVG-injected
+ vertical line segments to better approximate stems
+ - Non-uniform y-axis tick spacing (-0.4, -0.2, 0, 0.5, 1.0) — the 0→0.5 gap is 2.5×
+ the -0.2→0 gap, which can mislead scale perception; prefer uniform ticks like
+ [-0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0]
+ - _inject_ci_lines helper function deviates from the KISS flat-structure ideal —
+ acceptable but noted
+ - 'Visual refinement could be stronger: panel spacing and whitespace utilization
+ inside each panel could be improved'
+ image_description: |-
+ Light render (plot-light.png):
+ Background: Warm off-white (~#FAF8F1) — correct theme surface
+ Chrome: Title "acf-pacf · python · pygal · anyplot.ai" in dark ink at top of ACF panel — readable. Y-axis labels "ACF" and "PACF" in dark ink on left — readable. X-axis "Lag" label at bottom in dark ink — readable. Tick labels (0, 4, 8, ... for ACF; 1, 5, 9, ... for PACF) in muted dark tone — readable. "95% CI: ±0.139" amber annotation in upper-right corner — readable.
+ Data: Bars colored brand green (#009E73) for significant correlations, muted gray for non-significant. ACF panel shows clear seasonal pattern (spikes at lags 12, 24, 36). PACF shows characteristic AR(1) spike at lag 1 and rapid decay. Amber dashed CI lines at ±0.139. Muted zero baseline line. First series uses #009E73 (correct).
+ Legibility verdict: PASS — all text and data elements clearly readable on light background.
+
+ Dark render (plot-dark.png):
+ Background: Warm near-black (~#1A1A17) — correct dark theme surface
+ Chrome: Title in light cream color — clearly readable against dark background. Y-axis labels "ACF"/"PACF" in light text — readable. X-axis "Lag" label in light text — readable. Tick labels in light/muted-light text — readable. "95% CI: ±0.139" amber annotation visible. No dark-on-dark text failures detected.
+ Data: Bar colors identical to light render — brand green (#009E73) for significant, muted gray for non-significant. Data colors unchanged across themes (correct — only chrome flips). Amber dashed CI lines remain visible.
+ Legibility verdict: PASS — all text readable against dark background, no dark-on-dark failures.
criteria_checklist:
visual_quality:
- score: 27
+ score: 28
max: 30
items:
- id: VQ-01
@@ -46,44 +60,51 @@ review:
score: 7
max: 8
passed: true
- comment: Font sizes explicitly set (title=48, labels=30, major_labels=30).
- All text clearly readable.
+ comment: 'All text readable in both themes; minor: non-uniform y-axis tick
+ spacing (-0.4, -0.2, 0, 0.5, 1.0) subtly distorts scale perception'
- id: VQ-02
name: No Overlap
- score: 6
+ score: 5
max: 6
passed: true
- comment: No overlapping text. Major x-labels every 4 prevents crowding.
+ comment: No text overlaps; tightly packed bars in ACF lags 4-8 are dense but
+ no collision
- id: VQ-03
name: Element Visibility
- score: 5
+ score: 6
max: 6
passed: true
- comment: Bars clearly visible with good color contrast between significant
- and non-significant values.
+ comment: Significant bars (green) and non-significant (gray) clearly distinguishable;
+ CI amber lines and zero baseline visible in both renders
- id: VQ-04
name: Color Accessibility
- score: 4
- max: 4
+ score: 2
+ max: 2
passed: true
- comment: Blue/light blue scheme is colorblind-safe. Red confidence lines have
- good contrast.
+ comment: Brand green / muted gray / amber are CVD-safe; no red-green as sole
+ signal
- id: VQ-05
name: Layout & Canvas
- score: 3
+ score: 4
max: 4
passed: true
- comment: Two stacked charts fill canvas reasonably well. Some wasted vertical
- space below Lag label.
+ comment: Canvas gate passed (3200x1800); two-panel composition clean; no overflow
+ or clipping
- id: VQ-06
name: Axis Labels & Title
score: 2
max: 2
passed: true
- comment: ACF, PACF, and Lag are descriptive and appropriate. Correlations
- are unitless.
+ comment: ACF/PACF y-labels, Lag x-label, correct title format
+ - id: VQ-07
+ name: Palette Compliance
+ score: 2
+ max: 2
+ passed: true
+ comment: 'First series #009E73; non-significant uses INK_MUTED anchor; CI
+ uses ANYPLOT_AMBER anchor; backgrounds correct for both themes'
design_excellence:
- score: 13
+ score: 12
max: 20
items:
- id: DE-01
@@ -91,22 +112,22 @@ review:
score: 5
max: 8
passed: true
- comment: Custom color palette with meaningful significance differentiation.
- Above defaults but not publication-level.
+ comment: 'Above default: semantic color split, amber CI lines, corner annotation,
+ rounded bars show design intent'
- id: DE-02
name: Visual Refinement
- score: 4
+ score: 3
max: 6
passed: true
- comment: Subtle plot background, light grid lines, no x-guides, emphasized
- zero baseline.
+ comment: Y-axis-only grid, minimal chrome, subtle panel divider; whitespace
+ and spine treatment could be stronger
- id: DE-03
name: Data Storytelling
score: 4
max: 6
passed: true
- comment: Color differentiation between significant and non-significant lags
- creates immediate visual hierarchy.
+ comment: Green/gray semantic split immediately directs eye to significant
+ lags; seasonal pattern and AR cutoff visually prominent
spec_compliance:
score: 14
max: 15
@@ -116,29 +137,28 @@ review:
score: 4
max: 5
passed: true
- comment: Correct dual-panel ACF/PACF layout. Bars instead of stems due to
- pygal limitation.
+ comment: Correct ACF/PACF dual-panel concept; spec requires stem lines but
+ pygal.Bar produces filled bars — acceptable limitation
- id: SC-02
name: Required Features
score: 4
max: 4
passed: true
- comment: 'All spec features present: ACF top, PACF bottom, 95% CI lines, correct
- lag ranges.'
+ comment: ACF top/PACF bottom, 95% CI dashed lines, lag 0 in ACF, PACF from
+ lag 1, 36 lags all present
- id: SC-03
name: Data Mapping
score: 3
max: 3
passed: true
- comment: X-axis shows lag numbers, Y-axis shows correlation values. Correctly
- mapped.
+ comment: Lag on x-axis, correlation values on y-axis, all lags correctly displayed
- id: SC-04
name: Title & Legend
score: 3
max: 3
passed: true
- comment: Title format correct. Legend appropriately hidden for single-series
- charts.
+ comment: Title matches required format; legend omitted appropriately for semantically-colored
+ single-series
data_quality:
score: 15
max: 15
@@ -148,55 +168,58 @@ review:
score: 6
max: 6
passed: true
- comment: Shows seasonal pattern, AR component, positive/negative correlations,
- significant and non-significant lags.
+ comment: Both ACF and PACF shown; CI lines; significant/non-significant coloring;
+ zero baseline; 36 lags
- id: DQ-02
name: Realistic Context
score: 5
max: 5
passed: true
- comment: Airline-style passenger data with trend and seasonality. Classic
- neutral time series example.
+ comment: Monthly airline-style passenger data with trend + 12-period seasonality;
+ neutral domain; 200 observations
- id: DQ-03
name: Appropriate Scale
score: 4
max: 4
passed: true
- comment: 200 observations, realistic amplitudes, correlations in [-1, 1] range.
+ comment: Y-range [-0.5, 1.1] ACF / [-0.5, 1.0] PACF covers all values; 36
+ lags appropriate for n=200
code_quality:
score: 9
max: 10
items:
- id: CQ-01
name: KISS Structure
- score: 3
+ score: 2
max: 3
passed: true
- comment: Follows imports, data, plot, save structure. No functions or classes.
+ comment: 'Two helper functions: hex_to_rgb (small utility) and _inject_ci_lines
+ (SVG injection, justified by pygal API limitation)'
- id: CQ-02
name: Reproducibility
score: 2
max: 2
passed: true
- comment: np.random.seed(42) set.
+ comment: np.random.seed(42) present
- id: CQ-03
name: Clean Imports
score: 2
max: 2
passed: true
- comment: All imports used.
+ comment: All imports used; no dead imports
- id: CQ-04
name: Code Elegance
- score: 1
+ score: 2
max: 2
passed: true
- comment: SVG manipulation adds complexity but is justified by pygal limitations.
+ comment: Good use of common_config dict; per-bar color dict is idiomatic pygal;
+ sys.path workaround documented
- id: CQ-05
name: Output & API
score: 1
max: 1
passed: true
- comment: Saves as plot.png and plot.html. Current API used.
+ comment: Saves plot-{THEME}.png and plot-{THEME}.html correctly
library_mastery:
score: 7
max: 10
@@ -206,26 +229,27 @@ review:
score: 4
max: 5
passed: true
- comment: Good use of pygal.Bar, Style class, per-value color dicts, x_labels_major_every,
- rounded_bars.
+ comment: Good use of Style object, per-bar color dict, x_labels_major_every,
+ render() for SVG bytes
- id: LM-02
name: Distinctive Features
score: 3
max: 5
passed: true
- comment: Per-value color customization, SVG rendering for post-processing,
- HTML export with native interactivity.
+ comment: Per-bar color via dict syntax, HTML interactive output, SVG namespace
+ manipulation for CI injection
verdict: APPROVED
impl_tags:
dependencies:
- statsmodels
- pillow
techniques:
+ - subplots
- annotations
- html-export
+ - manual-ticks
patterns:
- data-generation
dataprep:
- time-series
- styling:
- - grid-styling
+ styling: []