{"spec_id":"scatter-matrix","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nscatter-matrix: Scatter Plot Matrix\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-09\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\n\n\n# Theme tokens\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\n# Okabe-Ito palette\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data: Financial metrics across market segments\nnp.random.seed(42)\nn_samples = 120\n\n# Three market segments\nsegments = np.repeat([\"Growth\", \"Value\", \"Dividend\"], n_samples // 3)\n\n# Generate financial metrics with realistic distributions\ndata = {\n    \"Annual Return (%)\": np.concatenate(\n        [\n            np.random.exponential(8, n_samples // 3) + 15,  # Growth: high return\n            np.random.exponential(5, n_samples // 3) + 8,  # Value: moderate return\n            np.random.exponential(4, n_samples // 3) + 5,  # Dividend: steady return\n        ]\n    ),\n    \"Volatility (%)\": np.concatenate(\n        [\n            np.random.exponential(3, n_samples // 3) + 18,  # Growth: high volatility\n            np.random.exponential(2, n_samples // 3) + 12,  # Value: medium volatility\n            np.random.exponential(1.5, n_samples // 3) + 8,  # Dividend: low volatility\n        ]\n    ),\n    \"P/E Ratio\": np.concatenate(\n        [\n            np.random.exponential(5, n_samples // 3) + 22,  # Growth: high multiples\n            np.random.exponential(3, n_samples // 3) + 12,  # Value: low multiples\n            np.random.exponential(2, n_samples // 3) + 16,  # Dividend: moderate multiples\n        ]\n    ),\n    \"Dividend Yield (%)\": np.concatenate(\n        [\n            np.random.exponential(0.4, n_samples // 3) + 0.5,  # Growth: low yield\n            np.random.exponential(0.6, n_samples // 3) + 1.5,  # Value: moderate yield\n            np.random.exponential(0.8, n_samples // 3) + 3.5,  # Dividend: high yield\n        ]\n    ),\n    \"Segment\": segments,\n}\n\ndf = pd.DataFrame(data)\n\n# Set theme for the entire figure\nsns.set_theme(\n    style=\"whitegrid\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.10,\n        \"grid.linewidth\": 0.8,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\nsns.set_context(\"talk\", font_scale=1.2)\n\n# Create pairplot with scatter matrices\ng = sns.pairplot(\n    df,\n    hue=\"Segment\",\n    palette=IMPRINT,\n    diag_kind=\"kde\",\n    plot_kws={\"s\": 60, \"alpha\": 0.7, \"edgecolor\": PAGE_BG, \"linewidth\": 0.5},\n    diag_kws={\"linewidth\": 2.5, \"fill\": True, \"alpha\": 0.4},\n    corner=False,\n    height=2.8,\n    aspect=1.0,\n)\n\n# Update title\ng.figure.suptitle(\"scatter-matrix · seaborn · anyplot.ai\", fontsize=28, y=1.00, fontweight=\"medium\")\n\n# Update legend using seaborn's move_legend (non-private API)\nif g._legend is not None:\n    g._legend.set_title(\"Segment\")\n    g._legend.get_title().set_fontsize(16)\n    for text in g._legend.get_texts():\n        text.set_fontsize(14)\n\n# Adjust label sizes\nfor ax in g.axes.flatten():\n    if ax is not None:\n        ax.tick_params(axis=\"both\", labelsize=13)\n        xlabel = ax.get_xlabel()\n        ylabel = ax.get_ylabel()\n        if xlabel:\n            ax.set_xlabel(xlabel, fontsize=16, color=INK)\n        if ylabel:\n            ax.set_ylabel(ylabel, fontsize=16, color=INK)\n\nplt.tight_layout()\ng.figure.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}