Skip to content

Commit 747b21c

Browse files
Merge branch 'main' into implementation/facet-grid/matplotlib
2 parents 6007453 + 27a1eef commit 747b21c

2 files changed

Lines changed: 244 additions & 166 deletions

File tree

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,112 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
facet-grid: Faceted Grid Plot
3-
Library: seaborn 0.13.2 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-30
3+
Library: seaborn 0.13.2 | Python 3.13.13
4+
Quality: 90/100 | Updated: 2026-05-13
55
"""
66

7+
import os
8+
9+
import matplotlib.pyplot as plt
710
import numpy as np
811
import pandas as pd
912
import seaborn as sns
1013

1114

12-
# Data
15+
# Theme tokens
16+
THEME = os.getenv("ANYPLOT_THEME", "light")
17+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
18+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
19+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
20+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
21+
INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
22+
BRAND = "#009E73"
23+
24+
# Data - Differentiated scenario: Production Cost vs Profit Margin by Product Line and Month
1325
np.random.seed(42)
1426

15-
# Create dataset with two categorical faceting variables
16-
categories_row = ["Region A", "Region B", "Region C"]
17-
categories_col = ["Q1", "Q2", "Q3", "Q4"]
27+
product_lines = ["Electronics", "Apparel", "Food"]
28+
months = ["Jan", "Feb", "Mar", "Apr"]
1829

1930
data = []
20-
for row_cat in categories_row:
21-
for col_cat in categories_col:
22-
n_points = 25
23-
# Vary the relationship by region and quarter
24-
base_slope = 0.6 + 0.2 * categories_row.index(row_cat)
25-
intercept = 10 + 5 * categories_col.index(col_cat)
26-
27-
x = np.random.uniform(5, 30, n_points)
28-
noise = np.random.normal(0, 3, n_points)
29-
y = intercept + base_slope * x + noise
31+
for product_idx, product in enumerate(product_lines):
32+
for month_idx, month in enumerate(months):
33+
n_points = 30
34+
# Vary profit margin by product line (Electronics: high margin but higher cost,
35+
# Apparel: moderate, Food: low margin, high volume)
36+
base_margin = 15 + 10 * product_idx
37+
margin_noise = np.random.normal(0, 3, n_points)
38+
39+
# Cost varies by month (seasonality)
40+
base_cost = 800 + 200 * month_idx
41+
cost_var = np.random.uniform(-100, 100, n_points)
42+
43+
# Profit margin increases with cost for some products
44+
cost = base_cost + cost_var
45+
profit_margin = base_margin + 0.01 * (cost - base_cost) + margin_noise
46+
profit_margin = np.clip(profit_margin, 5, 40)
3047

3148
for i in range(n_points):
3249
data.append(
33-
{"Marketing Spend ($k)": x[i], "Sales Revenue ($k)": y[i], "Region": row_cat, "Quarter": col_cat}
50+
{
51+
"Production Cost ($)": cost[i],
52+
"Profit Margin (%)": profit_margin[i],
53+
"Product Line": product,
54+
"Month": month,
55+
}
3456
)
3557

3658
df = pd.DataFrame(data)
3759

38-
# Plot
39-
sns.set_context("talk", font_scale=1.3)
40-
sns.set_style("whitegrid")
60+
# Setup theme
61+
sns.set_theme(
62+
style="ticks",
63+
rc={
64+
"figure.facecolor": PAGE_BG,
65+
"axes.facecolor": PAGE_BG,
66+
"axes.edgecolor": INK_SOFT,
67+
"axes.labelcolor": INK,
68+
"text.color": INK,
69+
"xtick.color": INK_SOFT,
70+
"ytick.color": INK_SOFT,
71+
"grid.color": INK_MUTED,
72+
"grid.alpha": 0.10,
73+
"legend.facecolor": ELEVATED_BG,
74+
"legend.edgecolor": INK_SOFT,
75+
},
76+
)
4177

42-
g = sns.FacetGrid(df, row="Region", col="Quarter", height=4.5, aspect=1.1, margin_titles=True)
78+
# Plot
79+
g = sns.FacetGrid(df, row="Product Line", col="Month", height=3.8, aspect=1.1, margin_titles=True)
4380

81+
# Map scatterplot with regression line
4482
g.map_dataframe(
45-
sns.scatterplot,
46-
x="Marketing Spend ($k)",
47-
y="Sales Revenue ($k)",
48-
color="#306998",
49-
s=150,
50-
alpha=0.7,
51-
edgecolor="white",
52-
linewidth=0.5,
83+
sns.regplot,
84+
x="Production Cost ($)",
85+
y="Profit Margin (%)",
86+
scatter_kws={"color": BRAND, "s": 140, "alpha": 0.75, "edgecolor": PAGE_BG, "linewidths": 0.8},
87+
line_kws={"color": INK_SOFT, "linewidth": 2.5, "alpha": 0.6},
88+
ci=None,
5389
)
5490

5591
# Styling
56-
g.set_titles(row_template="{row_name}", col_template="{col_name}", size=20)
57-
g.set_axis_labels("Marketing Spend ($k)", "Sales Revenue ($k)", fontsize=18)
92+
g.set_titles(row_template="{row_name}", col_template="{col_name}", size=18, fontweight="medium")
5893

59-
for ax in g.axes.flat:
94+
# Remove y-axis label repetition: only show on leftmost column
95+
for i, ax in enumerate(g.axes.flat):
6096
ax.tick_params(axis="both", labelsize=14)
61-
ax.grid(True, alpha=0.3, linestyle="--")
97+
ax.grid(True, alpha=0.12, linestyle="-", linewidth=0.7)
98+
99+
# Only leftmost column keeps y-axis label
100+
if i % 4 != 0:
101+
ax.set_ylabel("")
102+
103+
# Set labels once globally
104+
g.set_axis_labels("Production Cost ($)", "Profit Margin (%)", fontsize=18)
62105

63-
g.figure.suptitle("facet-grid · seaborn · pyplots.ai", fontsize=26, fontweight="bold", y=1.02)
106+
# Add main title
107+
g.figure.suptitle("facet-grid · seaborn · anyplot.ai", fontsize=26, fontweight="medium", y=0.995, color=INK)
64108

65109
g.tight_layout()
66110

67111
# Save
68-
g.savefig("plot.png", dpi=300, bbox_inches="tight")
112+
plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG)

0 commit comments

Comments
 (0)