#!/usr/bin/env python3 # stil_04.py """ Gemeinsamer Unterbau der Diagramm-Generatoren: Farben, Grundeinstellungen und das Schreiben der SVG-Datei. Warum es das gibt: Elf neue Generatoren trugen sonst elfmal denselben Vorspann. Eine Zeile daraus ist besonders heikel - plt.rcParams["svg.hashsalt"] = "or-mit-python-v04" Ohne sie wuerfelt matplotlib die clip-path-IDs je Figure neu; die Datei aendert sich dann bei JEDEM Lauf, ohne dass sich am Bild etwas geaendert haette. Das faellt nicht sofort auf, sondern erst als unlesbarer git-diff - und dann sucht man die Ursache lange. Dasselbe gilt fuer metadata={"Date": None} beim Speichern: Sonst steht der Schreibzeitstempel auf die Mikrosekunde im SVG. Die 33 aelteren Generatoren setzen beides jeweils selbst. Sie bleiben unveraendert - eine Umstellung waere ein eigener Schritt und braeuchte den Nachweis, dass jedes einzelne Bild byte-identisch bleibt. Benutzung: from stil_04 import FARBEN, neue_figur, speichere figur, achse = neue_figur(breite=7.6, hoehe=4.6) ... speichere(figur, "kap_einfuehrung_kombinatorik") """ from __future__ import annotations import os import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt # Reproduzierbare SVG-Ausgabe - siehe Modulkommentar. plt.rcParams["svg.hashsalt"] = "or-mit-python-v04" # Serifenlos und ueberall vorhanden. Bewusst kein Stylesheet von seaborn: Das # Buch hat eine eigene Palette, und zwei Stilsysteme nebeneinander sehen nach # zwei Buechern aus. plt.rcParams["font.family"] = "DejaVu Sans" plt.rcParams["axes.grid"] = True plt.rcParams["grid.linestyle"] = ":" plt.rcParams["grid.alpha"] = 0.4 plt.rcParams["axes.spines.top"] = False plt.rcParams["axes.spines.right"] = False BASIS = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BILDER = os.path.join(BASIS, "bilder_04") # Die Palette des Buchs - dieselben Werte wie in den 33 vorhandenen Diagrammen # und auf der Titelseite. Die Namen sagen, wofuer die Farbe steht, nicht wie # sie aussieht: So bleibt die Bedeutung erhalten, falls ein Ton je gewechselt # wird. FARBEN = { "haupt": "#4338ca", # Indigo - die primaere Groesse, Zielfunktion "zweit": "#0891b2", # Teal - die Vergleichsgroesse "warnung": "#b45309", # Amber - teuer, aber zulaessig "gut": "#059669", # Emerald - Optimum, zulaessige Menge "fehler": "#be123c", # Rose - unzulaessig, Verlust, Bruch "akzent": "#7c3aed", # Violett - Schranken, Niveaulinien "text": "#334155", # Slate - Beschriftung "gedaempft": "#64748b", # Slate hell - Nebeninformation "linie": "#94a3b8", # Hilfslinien "flaeche": "#f1f5f9", # Hinterlegte Flaechen } def neue_figur(breite: float = 7.6, hoehe: float = 4.6, **kwargs): """Figure und Achse in der Standardgroesse des Buchs.""" return plt.subplots(figsize=(breite, hoehe), **kwargs) def speichere(figur, name: str) -> str: """Schreibt bilder_04/.svg und meldet den Pfad. Nur SVG: Das PDF bindet die Bilder ueber \\includesvg (inkscape) ein, und PNG-Zweitfassungen gab es in diesem Projekt schon einmal - sie wurden von nirgendwo referenziert und mussten wieder geloescht werden.""" figur.tight_layout() os.makedirs(BILDER, exist_ok=True) pfad = os.path.join(BILDER, f"{name}.svg") figur.savefig(pfad, format="svg", dpi=160, bbox_inches="tight", metadata={"Date": None}) plt.close(figur) print(f"geschrieben: {pfad}") return pfad