storytelling-viz: Fertige Grafiken zum direkten Verwenden
Das Ziel ist eine Grafik, die direkt in einen Bericht, ein Dokument oder eine Fachzeitschrift eingefügt werden kann – kein schnell gekritzelter Balkenchart. Sie muss drei Kriterien erfüllen:
- Der Diagrammtyp passt. Der Typ entspricht dem, was verglichen wird, der Fokus ist klar, und die Daten werden direkt beschriftet (keine Legende nötig).
- Sie funktioniert mit echten Daten. Lange Labels, negative Werte, fehlende Werte, viele Kategorien und Ausreißer werden korrekt dargestellt.
- Sie erfüllt die Ausgabespezifikation. Größe, Schriftgröße, Linienstärken, Format und Schrifteinbettung entsprechen den Vorgaben.
Dieses Skill kümmert sich nur um die Grafik. Themenauswahl, Analyse und Berichtsstruktur sind nicht Teil dieses Skills.
Arbeitsablauf
- Szenario bestimmen. Das Szenario bestimmt die Standardeinstellungen für Farbe, Fußnoten, Zahlen usw. (siehe „Vereinbarungen für die zwei Szenarien“):
- Geschäftsbericht: Grafiken mit Geschäftskennzahlen für Fachabteilungen oder das Management, unabhängig von Rhythmus und Anlass (Wochenbericht, Monatsbericht, tägliches Dashboard, Ursachenanalyse, Management-/Vorstands-/Strategiesitzungsseiten). Das Entscheidungskriterium ist „ob der Inhalt aus Geschäftskennzahlen besteht und der Leser darauf basierend Geschäftsentscheidungen treffen muss“, nicht „ob es sich um einen Wochenbericht handelt“.
- Allgemein / Veröffentlichung: Analyse- oder Forschungsdokumente, experimentelle Ergebnisse, Webseiten, Artikelabbildungen usw.
- Bei Unsicherheit nach dem Geschäftsbericht-Szenario behandeln (strengere Konventionen, nur eine zusätzliche Fußnote). Beim Geschäftsbericht-Szenario muss zuerst
references/business.mdgelesen werden, auch wenn der Beispielcode bereits ausreichend erscheint.
- Funktion nach „Was wird verglichen“ auswählen. Siehe Tabelle zur Funktionsauswahl unten; beide Szenarien verwenden dieselbe Tabelle.
- Ausgabespezifikation wählen. Mit
spec=angeben (Präsentationsfolie, Dokument, Fachzeitschrift …). - Grafik erstellen und automatische Prüfergebnisse ansehen.
figure()/save()gibt nach dem RendernQA … okaus oder listet jede Warnung auf; das.qa-Attribut des Rückgabewerts enthält dieselbe Liste (leere Liste = bestanden). Liegen Warnungen vor, korrigieren, nicht ausliefern. - PNG öffnen und Checkliste durchgehen. Das generierte PNG mit Read öffnen und Punkt für Punkt der Checkliste am Ende überprüfen.
Kurzstart
# /// script
# dependencies = ["plotnine>=0.15,<0.16", "pandas", "pillow", "pypdf"]
# ///
import sys; sys.path.insert(0, "<skill>/scripts")
from viz_common import figure, titled, set_lang, save
import charts as C # Allgemeine Diagrammfunktionen
import biz as B # Geschäftsbericht-Diagrammfunktionen (können mit C. gemischt werden)
set_lang("en") # oder "zh" (Standard)
c = C.bar_rank(df, "channel", "gmv", highlight="POS", top_n=8, fmt="num")
figure([[(titled(c, title="POS ist der einzige Kanal, der geschrumpft ist"), 1)]],
spec="doc", name="fig1", outdir="out")
save(c, "fig2", spec="journal-1col", outdir="out") # Fachzeitschrift, Einzelgrafik: ohne Titel
# Geschäftsbericht: gleiche figure(), aber Fußnote mit Berechnungsgrundlage erforderlich
k = B.kpi_cards([dict(label="GMV (MTD)", value=16.5e6, prev=15.9e6, target=57e6, progress=0.29)])
figure([[(k, 1)]], spec="doc", size=(6.5, 2), name="kpi", outdir="out",
caption="Basis: bezahlte Bestellungen GMV (USD); MTD bis 9. Okt vs. 1.–9. Sep.")
Funktionsauswahl
Suche nach dem, was verglichen werden soll. C. = charts.py, B. = biz.py; mit ★ markierte Funktionen sind für Geschäftsberichte konzipiert, können aber in jedem Szenario verwendet werden.
| Vergleich | Funktion | Wichtige Punkte |
|---|---|---|
| Rangordnung, Zusammensetzung zu einem Zeitpunkt, positive/negative Werte | C.bar_rank(df, cat, value, highlight=, top_n=, fmt=) | Automatische Sortierung; Werte über top_n werden als „Andere/Other“ zusammengefasst; Werte innerhalb oder außerhalb des Balkens beschriftet |
| Was hat die Veränderung verursacht (Skala + Wachstum + Beitrag nach Dimension) | ★ B.contrib_table(df, dim, prev, cur, top_n=, growth_alert=) | Databalken für Skala, ▲▼ Wachstum, Änderung, Anteil an Gesamtänderung; Summenzeile oben |
| Trend: 1–N Linien zusammen | C.line_trend(df, x, y, group=, highlight=, band=, ref=) | Direkte Beschriftung am Linienende; automatisch zweistufige Monatsbeschriftung; Lücken bei fehlenden Werten; band= für Konfidenzband |
| Trend: Mehrere Gruppen getrennt betrachten | C.small_multiples(df, x, y, facet, highlight=) | Alle Teilgrafiken haben dieselbe y-Skala; graue Hintergrundlinien sind andere Gruppen |
| Trend: Geschäftskennzahl mit Vorjahresvergleich | ★ B.trend(df, date, value, compare="month"/"year", events=, as_of=, period_end=) | Automatisch synchronisierte Vorjahreslinie; Ereignisse markieren; unvollständige Periode gestrichelt + Prognose |
| Fortschritt: Kumuliert im Zeitraum vs. Ziel | ★ B.cumulative_vs_target(df, date, value, target, start, end, as_of=, prior=) | Kumulierter Istwert, Ziellinie, vorherige Kumulierung, Prognose basierend auf Durchschnitt |
| Ist vs. Ziel (mehrere Zeilen) | ★ B.bullet(df, cat, actual, target, progress=) | Ist-Balken + Ziel-Linie + „sollte gemäß Fortschritt erreicht sein“-Linie; hinter dem Fortschritt zurückliegende Zeilen rot |
| Ist vs. Bereich (Prognoseintervall, Normalbereich) | C.range_dot(df, cat, low, high, value, flag="below", bench=) | Außerhalb liegende Elemente in Fokusfarbe; bench= für Basiszeile |
| Zwei Werte pro Gruppe (Vorher/Nachher, Plan/Ist) | C.dumbbell(df, cat, start, end, labels=, highlight=) | Offener Punkt = Start, gefüllter Punkt = Ende; nach Ende sortiert; jede Zeile mit Änderungsrate |
| Erste und letzte Periode, große Skalenunterschiede zwischen Gruppen | C.slope(df, cat, start, end, mode="change", groups=) | Bei mode="change" starten alle Linien bei 0 %; Zeilen mit Startwert 0 werden entfernt und eine WARNING ausgegeben |
| Wasserfalldiagramm: Vorperiode → Beiträge → Aktuelle Periode | C.waterfall(df, cat, delta, start=, end_label=) | Standard neutrale Farben + Vorzeichen; bei geschäftlich sinnvollen gut/schlecht up=PAL.good, down=PAL.bad |
| Kennzahlenzerlegung (GMV = Nutzer × Häufigkeit × Durchschnittswert) | ★ B.driver_tree(nodes) | Jeder Knoten: aktueller Wert, ▲▼ Änderung, Beitrag (multiplikativ: logarithmischer Anteil, additiv: Änderung) |
| Zusammensetzung: Anteile mehrerer Gruppen | C.stacked_100(df, cat, part, value, order=, focus_cat=) | Teile nach natürlicher Reihenfolge, einfarbiger Verlauf; Legende in chart.legend |
| 2D-Tabelle (Gruppe × Zeit, Gruppe × Gruppe) | C.heatmap(df, x, y, value, fmt=) | Weiß zu einfarbig, Farbskala basierend auf Perzentilen 2%–98%; dunkle Zellen mit weißer Schrift |
| Skala + Rate (Anträge und Bestehensquote) | ★ B.bar_line_dual(df, x, bar, line, line_range=) | Einzige erlaubte Doppelachse: Skala als Balken (links) + Rate als Linie (rechts), Rate-Achse von 0 oder festem Bereich |
| Verteilung | C.distribution(df, value, group=, kind="box"/"strip"/"hist") | Nach Median sortiert; Whisker 1,5×IQR; Stichprobe bei vielen Punkten |
| Zusammenhang zwischen zwei stetigen Variablen | C.scatter(df, x, y, label=, fit="linear", groups=, x_title=, y_title=) | OLS + Konfidenzband, R² anzeigen; nur hervorgehobene Punkte beschriften; Legende bei groups= in chart.legend |
| Schätzwert mit Konfidenzintervall | C.point_range(df, cat, est, low, high, ref=0) | Forest-Plot; rechts „Schätzwert [Untergrenze, Obergrenze]“ |
| Zusammenfassung einiger Schlüsselzahlen (oben im Bericht) | ★ B.kpi_cards([dict(label, value, prev, target, progress, spark, …), …]) | Große Zahlen, ▲▼ Änderung, Zielerreichungsgrad mit Zeitfortschritt, Mini-Trendlinie; Abweichungen nur rot |
Details zu den Parametern der ★-Funktionen (kpi_cards-Felder, driver_tree-Knotenstruktur, trend-events= / as_of=, cumulative_vs_target-prior=, Ausnahmeregeln, Synchronisierung der Vorperioden) siehe references/business.md.
Auswahl, wenn zwei Optionen in Frage kommen:
B.contrib_tablevsC.waterfall: Wenn Skala, Wachstum und Anteil gleichzeitig benötigt werden oder mehr als ca. 8 Dimensionen → Tabelle; um zu zeigen, „wie sich die Vorperiode Schritt für Schritt in die aktuelle Periode verwandelt hat“ und ≤ ca. 8 Elemente → Wasserfalldiagramm. In Ursachenanalysen oft nebeneinander.C.line_trendvsC.small_multiples: Wenn eine Linie hervorgehoben werden soll oder ≤ 4 Linien →line_trend(bei > 4 Linienhighlight=); um die Form jeder Gruppe einzeln zu betrachten, gleichwertige Gruppen →small_multiples. Einspaltig in Fachzeitschrift (3,5 Zoll) fasst > 5 Facetten nicht, alsoline_trend+highlight=.- Zwei Werte pro Gruppe: Zuerst Skala der Gruppen prüfen: ähnlich (max / min < ca. 10×) →
C.dumbbell. Bei Größenunterschied von > einer Größenordnung sind kleine Gruppen auf gemeinsamer Skala schwer erkennbar. Stattdessen Änderungsrate direkt zeichnen: ≤ ca. 8 Gruppen →C.slope(mode="change"); mehr Gruppen → Änderungsrate als Spalte berechnen,C.bar_rank(df, cat, "chg", fmt="pct")verwenden, absolute Skala in Labels oder daneben stehende Tabelle.
Gemeinsame Parameter und Rückgabewerte aller Funktionen:
highlight=: Kategorie-Name, Liste oder Funktion. Ausgewählte Elemente in Fokusfarbe, restliche grau, Kategorie-Name ebenfalls farbig und fett.fmt=:"num","pct","pp","int","raw", Formatstring oder Funktion;nd=steuert Dezimalstellen.- Rückgabe ist ein Panel-Objekt, das direkt in
figure()/save()eingesetzt wird;chart + plotnine-Schichtenkönnen weiter überlagert werden;chart.legendist eine einzeilige, farbige Legende, dietitled()automatisch verwendet.
Wenn keine passende Funktion vorhanden ist, selbst zeichnen:
- Mit
C.Frame(w, h, xr, yr, left=…, …)Platz um die Grafik für die tatsächliche Textbreite reservieren; Achsenbereich mitC.axis_range(lo, hi). - In
C.Canvas()Elemente wierect,seg,pt,text,line,bandzeichnen, mitcv.plot(fr)die Grafik erzeugen. - Als
C.Chart(build)verpacken, wobeibuild(w, h)das Layout erst nach Erhalt der endgültigen Größe berechnet.
Keine fest codierten Koordinaten oder Achsenbereiche im Code verwenden.
Vereinbarungen für die zwei Szenarien
Die Funktionen selbst zeichnen in beiden Szenarien gleich; die Unterschiede liegen in den folgenden Standardkonventionen. Im Code gibt es keinen „Szenario“-Parameter: ★-Funktionen haben eingebaute Geschäftsbericht-Darstellung (▲▼, Abweichungen nur rot) und lassen figure() bei fehlender Fußnote eine WARNING ausgeben; C.-Grafiken auf derselben Seite werden von dir gemäß der folgenden Tabelle parametrisiert (z. B. caption=, highlight=, up= / down=-Farben).
| Aspekt | Allgemein / Veröffentlichung | Geschäftsbericht |
|---|---|---|
| Steigen/Fallen | Nur wenn „gut“/„schlecht“ eine geschäftliche Bedeutung hat, good/bad verwenden, immer mit Vorzeichen oder Text | Immer ▲▼ + neutrale Farbe, kein Rot/Grün für Steigen/Fallen |
| Wann wird rot verwendet | Nur um „schlecht“ anzuzeigen | Nur wenn eine Abweichung vorliegt (hinter Plan / über Schwellwert / außerhalb historischem ±2σ); Abweichung in positive Richtung nur fett |
| „Schau hier“ für den Leser (z. B. Kanal, der Wachstum behindert) | highlight= (Fokusfarbe Orange) | Gleich; Orange bedeutet nur „schau hier“, nicht gut/schlecht; ob eine Abweichung vorliegt, wird durch ▲▼ und rot ausgedrückt |
| Fußnote mit Berechnungsgrundlage | Empfohlen | Pflicht (caption=): Zähler/Nenner, Währung, Zeitfenster, Vergleichsbasis; Fehlen führt zu WARNING von figure() |
| Vergleichsbasis | Nach Analysebedarf | Standard: Vormonatsvergleich, aktueller Monat kumuliert vs. gleicher Zeitraum Vorjahr (gleiche Anzahl Tage), Zielerreichung; Tageskennzahlen nach Wochentag synchronisiert |
| Unvollständige laufende Periode | Hell oder gestrichelt + „bis zum X. Tag“ | Gleich, plus Schätzung für gesamte Periode basierend auf Fortschritt |
| Zahlen | Nach Bereichsgewohnheiten | Beträge in K/M/B; Ratenänderungen in PP, Wachstum in %; Einheiten in Titel oder Anmerkung |
| Doppelachse | Nicht verwenden | Nur „Skala als Balken + Rate als Linie“ erlaubt (B.bar_line_dual) |
| Tortendiagramme / Ringdiagramme | Nach Möglichkeit vermeiden | Verboten |
| Übliche Spezifikationen | doc, web, journal-* | PPT mit slide; Feishu / Lark / Notion-Dokument oder Chat mit doc (PNG-Einbindung); wenn der Benutzer den Ort nicht angibt: doc |
Gründe und Gegenbeispiele finden sich in references/rules.md (Geschäftsberichtsteile B1–B7).
Ausgabespezifikationen (spec=)
| spec | Größe (Zoll) | Schriftgröße | Standardformat | Verwendung |
|---|---|---|---|---|
slide / slide-4x3 | 13,33×7,5 / 10×7,5 | 12 / 11,5 | Umriss-SVG, bearbeitbares SVG, PNG (150 dpi) | Präsentationsfolie |
web | 8×4,5 | 10,5 | SVG, PNG (200 dpi) | Webseite, E-Mail |
doc | 6,5×4 | 9 | PDF, SVG, PNG (300 dpi) | Einzelgrafik im Dokumenttext |
a4 / letter | Ganze Seite | 10 | PDF, SVG, PNG | Ganzseitiger Bericht |
journal-1col / -1.5col / -2col | Breite 3,5 / 5,35 / 7,2 | 7–7,5 | PDF, SVG, PNG (600 dpi) | Fachzeitschrift (89 / 136 / 183 mm) |
size=(w, h)kann die Standardgröße überschreiben, z. B. höhere Zeitschriftenabbildungen, flachere KPI-Kartenzeilen.- Schriftgrößen, Linienstärken und Punktgrößen skalieren mit der Spezifikation; PDF verwendet Type 42 eingebettete Schriftarten, erfüllt Zeitschriftenanforderungen.
- Zeitschriftenabbildungen haben keinen Titel, Bildunterschriften im Text: Einzelgrafik mit
save(chart, name, spec="journal-1col"); Mehrfachpanels mitfigure(rows, spec="journal-2col"), ohnetitle=, Panel-Beschriftung mittitled(chart, title="a"). figure()gibt eine gesamte Seite aus (optional mit Titel, Untertitel, Fußnote, mehreren Panels);save(chart, "fig2", spec="journal-1col")exportiert nur eine Grafik ohne Seitentitel und Fußnote. Für Geschäftsberichtefigure()verwenden (Fußnote).- Zwei SVG-Arten:
<name>.svgmit in Konturen umgewandelten Buchstaben (überall gleich);<name>_editable.svgbehält Buchstaben (in Figma/PPT bearbeitbar, aber gleiche Schriftart auf Zielrechner nötig). Für Bearbeitung in PPT letzteres, sonst ersteres oder PNG. slide/webstandardmäßig ohne PDF; bei Bedarfformats=("pdf", "png")übergeben.
Kombination mehrerer Panels
figure(rows, title=, subtitle=, caption=, spec=):rows=[[(panel, span), …], …],spanist relative Breite innerhalb der Zeile.- Zeilenhöhe Standard automatisch: Zeilen mit nur Text oder Tabelle werden nach Inhaltshöhe dimensioniert, Rest gleichmäßig verteilt.
titled(chart, title=, legend=, note=): Fügt Panel-Titel, Legendenzeile und Anmerkung oberhalb der Grafik hinzu;legendverwendet automatischchart.legend, wenn nicht angegeben.- Titel unterstützen Rich-Text-Markierung:
**fett**;[Phrase](focus)in Fettschrift und farbig. Farben:focus,brand,good,bad,muted,inkoder#hex. - Weitere Panel:
text_panel(para(...))für Absätze,table_panel(rows, header=)für kleine Tabellen (Zahlenspalten automatisch rechtsbündig),column(a, b)stapelt zwei Panels vertikal. - Jedes Panel wird basierend auf der endgültigen Größe einzeln gerendert, Schriftgröße also tatsächlicher Punktwert; beim Zusammenfügen der SVG werden Element-ID-Präfixe automatisch hinzugefügt, um Konflikte zu vermeiden.
Visuelle Regeln (Funktionen führen sie standardmäßig aus; beim Selbstzeichnen beachten)
- Farbhierarchie:
focus(Orange) markiert das Einzige, worauf geschaut werden soll, steht selbst nicht für gut/schlecht;brand(Dunkelblau) für reguläre Serien; Grau für Hintergrund und Referenz;good/badje nach Szenario (siehe Tabelle oben). - Gleiche Farbe = gleiche Bedeutung. Text-Schlüsselwörter und zugehörige Daten in derselben Farbe; Elemente mit unterschiedlicher Bedeutung nicht dieselbe Farbe teilen.
- Text muss lesbar sein. Textkontrast mindestens 4,5:1. Fokusfarbe als Text mit
readable(color)automatisch abdunkeln; Text auf dunklem Hintergrund mitink_on(fill). Funktionen handhaben das automatisch;Canvas.textprüft und warnt beim Selbstzeichnen. - Direkte Beschriftung statt Legende. Achsentitel dürfen keine Feldnamen sein. Wenn alle Balken mit Werten beschriftet sind, y-Achse und Gitter weglassen.
- Sortierung muss sinnvoll sein. Bei natürlicher Ordnung (Stufen, Grade) diese verwenden, sonst numerisch sortieren; Fokus-Element an prominentester Stelle; nicht alphabetisch sortieren.
- Achsen. Balkendiagramme müssen bei 0 beginnen; Liniendiagramme bei Daten nahe 0 mit 0 beginnen (
zero="auto"); zusammenhängende Panels dieselbe Skalierung; Doppelachse nur „Skala als Balken + Rate als Linie“. - Präzision. Ausreichend zur Unterscheidung. Zahlen immer durch Datenberechnung mit
pct/pp/num/fmt_valueformatieren, nicht manuell. - Diagrammtyp nach Vergleich wählen: Anteilsänderungen nicht mit absoluten Stapelsäulen; Zusammensetzung mehrerer Gruppen nicht mit mehreren Tortendiagrammen; bei > 4 Linien mit
highlight=Akzente setzen oder kleine Mehrfachgrafiken verwenden; Treemaps, Radardiagramme bei zwei Vergleichen, die > ca. 2 Sekunden brauchen, durch waagerechte Balken ersetzen. - Datenprobleme in der Grafik kennzeichnen. Unvollständige laufende Periode hell oder gestrichelt mit „bis zum X. Tag“; kleine Stichproben mit n; Lücken bei fehlenden Werten durch Linienbruch darstellen, nicht verbinden.
Details und Begründungen siehe references/rules.md; SWD-Designpraktiken für Grafiken siehe references/swd_practices.md.
Sprache und Layout
set_lang("zh" | "en")schaltet gleichzeitig Standardschriftart, Monatsbeschriftung (Chinesisch „1月\n2026“, Englisch „Jan\n2026“) und „Andere/Other“ um. Beträge standardmäßig in K/M/B in beiden Sprachen; für chinesische 万/亿set_number_style("cn")verwenden. Labels mit chinesischen Zeichen verwenden automatisch CJK-Schrift.T("其他", "Other")ruft je nach aktueller Sprache ab.- Chinesische Zeichenketten werden automatisch durch
zh()verarbeitet: Satzzeichen in vollbreite Zeichen, überflüssige Leerzeichen um vollbreite Satzzeichen entfernen, URLs und Abkürzungen bleiben unverändert. - Zeilenumbruchregeln: Zahlen und englische Wörter nicht trennen; Satzzeichen nicht am Zeilenanfang; linke Klammern nicht am Zeilenende.
- Beim Start wird die verwendete Schriftart ausgegeben. Bei
WARNING: no CJK fontmuss Noto Sans SC installiert werden.
Prüfung vor Auslieferung
Automatische Prüfung (Ausgabe von figure() oder .qa ansehen):
-
QA … ok: Keine überlappenden Buchstaben, keine über den Panelrand hinausragenden, keine durch den Zeichenbereich abgeschnittenen Elemente. - Keine Kontrastwarnung und keine Warnungen wie
rows do not fit,labels take most of the panel,cells too small,basis caption.
Manuelle Prüfung (PNG öffnen):
- Wenn der Titel abgedeckt wird und nur die Grafik angesehen wird, kann die Botschaft erkannt werden? Gibt es nur einen Fokus?
- Stimmen die Zahlen im Titel und in den Beschriftungen mit demselben Variablenwert überein wie die in der Grafik?
- Passt der Diagrammtyp zum Vergleich (siehe Funktionsauswahltabelle)? Ist die Sortierung sinnvoll? Haben zusammenhängende Panels dieselbe Skalierung?
- Entspricht die Farbverwendung den Szenariokonventionen? Kann nach Entfernen der Farbe gut/schlecht/steigen/fallen noch aus Symbolen oder Text abgelesen werden?
- Sind keine Standardlegenden, Feldnamen, 3D-Effekte oder Farbverläufe vorhanden?
- Entsprechen Größe und Schriftgröße der Zielspezifikation (Fachzeitschrift ca. 7 pt, Präsentationsfolie mindestens 12 pt)? Ist PDF exportiert, falls benötigt?
Geschäftsbericht zusätzlich:
- Ist die Fußnote mit Berechnungsgrundlage vollständig? Mit anderen Berichten abgeglichen (gleiche Zahl in verschiedenen Seiten eines Berichts konsistent)?
- Sind Einheiten, Dezimalstellen und Formatierung in der gesamten Grafik einheitlich?
Umgebung und Tests
- Abhängigkeiten:
plotnine>=0.15,<0.16(verifiziert mit 0.15.8 + matplotlib 3.11),pandas,pillow, für PDF-Export zusätzlichpypdf. Code inscripts/viz_common.py(Basiswerkzeuge, Spezifikationen, Export, QA),scripts/charts.py(C.) undscripts/biz.py(B.). - Ausgabeverzeichnis:
outdirauf ein für den Benutzer sichtbares Verzeichnis setzen; nicht in das Skill-Verzeichnis selbst schreiben. - Beispielgalerie:
uv run references/gallery.py [outdir](jedeC.-Funktion, chinesische Präsentationsfolie + englische Fachzeitschrift);uv run references/business_gallery.py [outdir](jedeB.-Funktion, chinesische Präsentationsfolie + englisches Dokument). Standardmäßig Ausgabe inout/im aktuellen Verzeichnis. - Regressionstests:
uv run references/tests/edge_cases.pytestet mit 38 Randdatensätzen unter zwei Spezifikationen (insgesamt 76 Fälle) das Verhalten der Funktionen und die erwartete QA; nach Änderungen an Grafikfunktionen muss dieser Test erneut ausgeführt werden und vollständig bestanden werden, bevor veröffentlicht werden kann. - Wenn plotnine in der Sandbox nicht installiert werden kann: Zuerst den matplotlib-Simulator
PYTHONPATH=<skill>/scripts/plotnine_previewfür Layout und QA verwenden (Linienstärken und Beschnittregeln identisch mit plotnine).QA okdes Simulators gilt nicht als Auslieferungsstandard: Das Skript dem Benutzer zum Ausführen mituv runauf dem lokalen Rechner übergeben und dem Benutzer explizit mitteilen, dass diese Grafik noch nicht mit echtem plotnine gerendert und geprüft wurde.