|
| 1 | +""" pyplots.ai |
| 2 | +subplot-mosaic: Mosaic Subplot Layout with Varying Sizes |
| 3 | +Library: matplotlib 3.10.8 | Python 3.13.11 |
| 4 | +Quality: 92/100 | Created: 2025-12-31 |
| 5 | +""" |
| 6 | + |
| 7 | +import matplotlib.pyplot as plt |
| 8 | +import numpy as np |
| 9 | + |
| 10 | + |
| 11 | +# Data |
| 12 | +np.random.seed(42) |
| 13 | + |
| 14 | +# Time series data for main overview chart |
| 15 | +dates = np.arange(100) |
| 16 | +sales = np.cumsum(np.random.randn(100) * 5 + 2) + 500 |
| 17 | + |
| 18 | +# Category data for bar chart |
| 19 | +categories = ["Product A", "Product B", "Product C", "Product D"] |
| 20 | +values = [85, 120, 95, 110] |
| 21 | + |
| 22 | +# Scatter data for correlation plot |
| 23 | +x_scatter = np.random.normal(50, 15, 80) |
| 24 | +y_scatter = x_scatter * 0.8 + np.random.normal(0, 10, 80) |
| 25 | + |
| 26 | +# Histogram data |
| 27 | +measurements = np.random.normal(100, 20, 200) |
| 28 | + |
| 29 | +# Metric values for small panels |
| 30 | +metrics = {"Growth": 12.5, "Conversion": 3.2, "Retention": 87.4} |
| 31 | + |
| 32 | +# Create mosaic layout: "AAB;AAB;CDE" pattern |
| 33 | +# A = large overview (spans 2 rows, 2 cols), B = bar chart (right side, 2 rows) |
| 34 | +# C, D, E = three small panels at bottom |
| 35 | +mosaic = """ |
| 36 | +AAB |
| 37 | +AAB |
| 38 | +CDE |
| 39 | +""" |
| 40 | + |
| 41 | +fig, axes = plt.subplot_mosaic(mosaic, figsize=(16, 9)) |
| 42 | + |
| 43 | +# A: Main time series overview |
| 44 | +axes["A"].plot(dates, sales, linewidth=3, color="#306998") |
| 45 | +axes["A"].fill_between(dates, sales.min(), sales, alpha=0.3, color="#306998") |
| 46 | +axes["A"].set_xlabel("Day", fontsize=18) |
| 47 | +axes["A"].set_ylabel("Cumulative Sales ($)", fontsize=18) |
| 48 | +axes["A"].set_title("Sales Overview", fontsize=22) |
| 49 | +axes["A"].tick_params(axis="both", labelsize=14) |
| 50 | +axes["A"].grid(True, alpha=0.3, linestyle="--") |
| 51 | + |
| 52 | +# B: Bar chart for categories |
| 53 | +bars = axes["B"].barh(categories, values, color="#FFD43B", edgecolor="#306998", linewidth=2) |
| 54 | +axes["B"].set_xlabel("Units Sold", fontsize=18) |
| 55 | +axes["B"].set_title("Product Performance", fontsize=22) |
| 56 | +axes["B"].tick_params(axis="both", labelsize=14) |
| 57 | +axes["B"].grid(True, alpha=0.3, linestyle="--", axis="x") |
| 58 | +# Add value labels |
| 59 | +for bar, val in zip(bars, values, strict=True): |
| 60 | + axes["B"].text(val + 2, bar.get_y() + bar.get_height() / 2, str(val), va="center", fontsize=14) |
| 61 | + |
| 62 | +# C: Scatter plot |
| 63 | +axes["C"].scatter(x_scatter, y_scatter, s=100, alpha=0.7, color="#306998", edgecolor="white", linewidth=1) |
| 64 | +axes["C"].set_xlabel("Feature X", fontsize=16) |
| 65 | +axes["C"].set_ylabel("Feature Y", fontsize=16) |
| 66 | +axes["C"].set_title("Correlation", fontsize=20) |
| 67 | +axes["C"].tick_params(axis="both", labelsize=12) |
| 68 | +axes["C"].grid(True, alpha=0.3, linestyle="--") |
| 69 | + |
| 70 | +# D: Histogram |
| 71 | +axes["D"].hist(measurements, bins=20, color="#306998", edgecolor="white", linewidth=1, alpha=0.8) |
| 72 | +axes["D"].set_xlabel("Value", fontsize=16) |
| 73 | +axes["D"].set_ylabel("Frequency", fontsize=16) |
| 74 | +axes["D"].set_title("Distribution", fontsize=20) |
| 75 | +axes["D"].tick_params(axis="both", labelsize=12) |
| 76 | +axes["D"].grid(True, alpha=0.3, linestyle="--", axis="y") |
| 77 | + |
| 78 | +# E: Metrics display |
| 79 | +axes["E"].set_xlim(0, 1) |
| 80 | +axes["E"].set_ylim(0, 1) |
| 81 | +axes["E"].axis("off") |
| 82 | +axes["E"].set_title("Key Metrics", fontsize=20) |
| 83 | +y_positions = [0.75, 0.45, 0.15] |
| 84 | +for (name, value), y_pos in zip(metrics.items(), y_positions, strict=True): |
| 85 | + axes["E"].text(0.5, y_pos, name, ha="center", va="center", fontsize=16, fontweight="bold") |
| 86 | + if name == "Growth": |
| 87 | + axes["E"].text(0.5, y_pos - 0.12, f"+{value}%", ha="center", va="center", fontsize=24, color="#306998") |
| 88 | + elif name == "Conversion": |
| 89 | + axes["E"].text(0.5, y_pos - 0.12, f"{value}%", ha="center", va="center", fontsize=24, color="#306998") |
| 90 | + else: |
| 91 | + axes["E"].text(0.5, y_pos - 0.12, f"{value}%", ha="center", va="center", fontsize=24, color="#306998") |
| 92 | +# Add box around metrics |
| 93 | +axes["E"].add_patch(plt.Rectangle((0.05, 0.02), 0.9, 0.96, fill=False, edgecolor="#306998", linewidth=2)) |
| 94 | + |
| 95 | +# Main title |
| 96 | +fig.suptitle("subplot-mosaic · matplotlib · pyplots.ai", fontsize=26, fontweight="bold", y=0.98) |
| 97 | + |
| 98 | +plt.tight_layout(rect=[0, 0, 1, 0.95]) |
| 99 | +plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
0 commit comments