{"spec_id":"line-styled","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nline-styled: Styled Line Plot\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_line,\n    ggplot,\n    labs,\n    scale_color_manual,\n    scale_linetype_manual,\n    scale_x_continuous,\n    theme,\n    theme_minimal,\n)\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - quarterly product performance over 3 years\nnp.random.seed(42)\nquarters = np.arange(1, 13)\nquarter_labels = [f\"Q{(i - 1) % 4 + 1} {2022 + (i - 1) // 4}\" for i in quarters]\n\n# Generate realistic sales trends for different product lines\nbase = 100\nproduct_a = base + np.cumsum(np.random.randn(12) * 5 + 3)\nproduct_b = base + np.cumsum(np.random.randn(12) * 4 + 1)\nproduct_c = base + np.cumsum(np.random.randn(12) * 6 - 0.5)\nproduct_d = base + np.cumsum(np.random.randn(12) * 3 + 2)\n\n# Create long-format DataFrame for plotnine\ndf = pd.DataFrame(\n    {\n        \"Quarter\": np.tile(quarters, 4),\n        \"Sales\": np.concatenate([product_a, product_b, product_c, product_d]),\n        \"Product\": [\"Product A\"] * 12 + [\"Product B\"] * 12 + [\"Product C\"] * 12 + [\"Product D\"] * 12,\n    }\n)\n\n# Define line styles and colors using Okabe-Ito palette\nlinetype_values = {\"Product A\": \"solid\", \"Product B\": \"dashed\", \"Product C\": \"dotted\", \"Product D\": \"dashdot\"}\ncolor_values = {\n    \"Product A\": IMPRINT[0],\n    \"Product B\": IMPRINT[1],\n    \"Product C\": IMPRINT[2],\n    \"Product D\": IMPRINT[3],\n}\n\n# Theme-adaptive styling\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG),\n    panel_grid_major=element_line(color=INK, size=0.3, alpha=0.15),\n    panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.08),\n    panel_border=element_rect(color=INK_SOFT, fill=None, size=0.5),\n    axis_title=element_text(color=INK, size=20),\n    axis_text=element_text(color=INK_SOFT, size=16),\n    axis_line=element_line(color=INK_SOFT, size=0.4),\n    plot_title=element_text(color=INK, size=24, weight=\"medium\"),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT, size=0.4),\n    legend_text=element_text(color=INK_SOFT, size=16),\n    legend_title=element_text(color=INK, size=18),\n    figure_size=(16, 9),\n)\n\n# Create plot\nplot = (\n    ggplot(df, aes(x=\"Quarter\", y=\"Sales\", color=\"Product\", linetype=\"Product\"))\n    + geom_line(size=1.8)\n    + scale_x_continuous(breaks=quarters, labels=quarter_labels, limits=(0.5, 12.5))\n    + scale_linetype_manual(values=linetype_values)\n    + scale_color_manual(values=color_values)\n    + labs(\n        title=\"line-styled · plotnine · anyplot.ai\",\n        x=\"Quarter\",\n        y=\"Sales (thousands USD)\",\n        color=\"Product Line\",\n        linetype=\"Product Line\",\n    )\n    + theme_minimal()\n    + anyplot_theme\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=300)\n"}