|
1 | | -""" pyplots.ai |
| 1 | +""" anyplot.ai |
2 | 2 | radar-basic: Basic Radar Chart |
3 | | -Library: seaborn 0.13.2 | Python 3.13.11 |
4 | | -Quality: 91/100 | Created: 2025-12-23 |
| 3 | +Library: seaborn 0.13.2 | Python 3.13.13 |
| 4 | +Quality: 86/100 | Updated: 2026-04-29 |
5 | 5 | """ |
6 | 6 |
|
| 7 | +import os |
| 8 | + |
7 | 9 | import matplotlib.pyplot as plt |
8 | 10 | import numpy as np |
9 | | -import pandas as pd |
10 | 11 | import seaborn as sns |
11 | 12 |
|
12 | 13 |
|
| 14 | +# Theme tokens |
| 15 | +THEME = os.getenv("ANYPLOT_THEME", "light") |
| 16 | +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
| 17 | +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" |
| 18 | +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
| 19 | +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" |
| 20 | + |
| 21 | +OKABE_ITO = ["#009E73", "#D55E00", "#0072B2", "#CC79A7", "#E69F00", "#56B4E9", "#F0E442"] |
| 22 | + |
| 23 | +sns.set_theme( |
| 24 | + style="ticks", |
| 25 | + rc={ |
| 26 | + "figure.facecolor": PAGE_BG, |
| 27 | + "axes.facecolor": PAGE_BG, |
| 28 | + "axes.edgecolor": INK_SOFT, |
| 29 | + "axes.labelcolor": INK, |
| 30 | + "text.color": INK, |
| 31 | + "xtick.color": INK_SOFT, |
| 32 | + "ytick.color": INK_SOFT, |
| 33 | + "grid.color": INK_SOFT, |
| 34 | + "grid.alpha": 0.15, |
| 35 | + "legend.facecolor": ELEVATED_BG, |
| 36 | + "legend.edgecolor": INK_SOFT, |
| 37 | + }, |
| 38 | +) |
| 39 | + |
13 | 40 | # Data - Employee performance comparison across competencies |
14 | 41 | categories = ["Communication", "Technical Skills", "Teamwork", "Leadership", "Problem Solving", "Creativity"] |
15 | 42 | employee_a_values = [85, 90, 75, 70, 88, 82] # Senior Developer |
16 | 43 | employee_b_values = [78, 65, 92, 85, 72, 75] # Team Lead |
17 | 44 |
|
18 | | -# Setup for radar chart |
19 | 45 | n_vars = len(categories) |
20 | 46 | angles = np.linspace(0, 2 * np.pi, n_vars, endpoint=False).tolist() |
21 | 47 | angles += angles[:1] # Close the polygon |
22 | 48 |
|
23 | | -# Close the polygons |
24 | 49 | employee_a = employee_a_values + employee_a_values[:1] |
25 | 50 | employee_b = employee_b_values + employee_b_values[:1] |
26 | 51 |
|
27 | | -# Create DataFrame for seaborn plotting |
28 | | -df = pd.DataFrame( |
29 | | - { |
30 | | - "Category": categories * 2, |
31 | | - "Score": employee_a_values + employee_b_values, |
32 | | - "Employee": ["Senior Developer"] * n_vars + ["Team Lead"] * n_vars, |
33 | | - "angle": (angles[:-1] * 2), |
34 | | - } |
35 | | -) |
36 | | - |
37 | | -# Apply seaborn styling with context for proper scaling |
38 | | -sns.set_theme(style="whitegrid", context="poster", font_scale=1.2) |
39 | | -palette = sns.color_palette("colorblind", 2) |
40 | | - |
41 | | -# Create square figure for radar chart (3600x3600 at 300 dpi = 12x12 inches) |
42 | | -fig, ax = plt.subplots(figsize=(12, 12), subplot_kw={"projection": "polar"}) |
| 52 | +# Plot - square canvas for symmetric radar chart (3600x3600 at 300 dpi) |
| 53 | +fig, ax = plt.subplots(figsize=(12, 12), subplot_kw={"projection": "polar"}, facecolor=PAGE_BG) |
| 54 | +ax.set_facecolor(PAGE_BG) |
43 | 55 |
|
44 | | -# Use seaborn scatterplot for data points on the polar axes |
45 | | -sns.scatterplot(data=df, x="angle", y="Score", hue="Employee", palette=palette, s=400, ax=ax, legend=False, zorder=5) |
| 56 | +color_a = OKABE_ITO[0] # #009E73 - Senior Developer (first series) |
| 57 | +color_b = OKABE_ITO[1] # #D55E00 - Team Lead |
46 | 58 |
|
47 | | -# Draw filled polygons and lines (matplotlib needed for fill and closed polygon) |
48 | | -color_senior = palette[0] |
49 | | -color_lead = palette[1] |
| 59 | +ax.fill(angles, employee_a, alpha=0.25, color=color_a) |
| 60 | +ax.plot(angles, employee_a, color=color_a, linewidth=3.5, label="Senior Developer") |
| 61 | +ax.scatter(angles[:-1], employee_a_values, color=color_a, s=150, zorder=5) |
50 | 62 |
|
51 | | -ax.fill(angles, employee_a, alpha=0.25, color=color_senior) |
52 | | -ax.plot(angles, employee_a, color=color_senior, linewidth=4, label="Senior Developer") |
| 63 | +ax.fill(angles, employee_b, alpha=0.25, color=color_b) |
| 64 | +ax.plot(angles, employee_b, color=color_b, linewidth=3.5, label="Team Lead") |
| 65 | +ax.scatter(angles[:-1], employee_b_values, color=color_b, s=150, zorder=5) |
53 | 66 |
|
54 | | -ax.fill(angles, employee_b, alpha=0.25, color=color_lead) |
55 | | -ax.plot(angles, employee_b, color=color_lead, linewidth=4, label="Team Lead") |
56 | | - |
57 | | -# Configure axes with larger tick labels |
| 67 | +# Style axes |
58 | 68 | ax.set_xticks(angles[:-1]) |
59 | | -ax.set_xticklabels(categories, fontsize=22, fontweight="medium") |
| 69 | +ax.set_xticklabels(categories, fontsize=20, color=INK, fontweight="medium") |
60 | 70 | ax.set_ylim(0, 100) |
61 | 71 | ax.set_yticks([20, 40, 60, 80, 100]) |
62 | | -ax.set_yticklabels(["20", "40", "60", "80", "100"], fontsize=18, color="gray") |
63 | | - |
64 | | -# Style grid |
65 | | -ax.grid(True, alpha=0.3, linestyle="-", linewidth=1.5) |
66 | | -ax.spines["polar"].set_visible(False) |
67 | | - |
68 | | -# Title with proper padding |
69 | | -ax.set_title("radar-basic · seaborn · pyplots.ai", fontsize=28, fontweight="bold", pad=35) |
70 | | - |
71 | | -# Legend positioned inside the plot area for better balance |
72 | | -ax.legend(loc="upper right", fontsize=18, framealpha=0.95, edgecolor="lightgray", fancybox=True) |
| 72 | +ax.set_yticklabels(["20", "40", "60", "80", "100"], fontsize=16, color=INK_SOFT) |
| 73 | + |
| 74 | +# Grid and spines |
| 75 | +grid_alpha = 0.20 if THEME == "light" else 0.25 |
| 76 | +ax.grid(True, alpha=grid_alpha, linestyle="-", linewidth=1.2, color=INK_SOFT) |
| 77 | +ax.spines["polar"].set_color(INK_SOFT) |
| 78 | +ax.spines["polar"].set_alpha(0.4) |
| 79 | + |
| 80 | +# Title |
| 81 | +ax.set_title("radar-basic · seaborn · anyplot.ai", fontsize=26, fontweight="medium", color=INK, pad=40) |
| 82 | + |
| 83 | +# Legend |
| 84 | +legend = ax.legend( |
| 85 | + loc="upper right", |
| 86 | + bbox_to_anchor=(1.35, 1.15), |
| 87 | + fontsize=18, |
| 88 | + framealpha=0.95, |
| 89 | + facecolor=ELEVATED_BG, |
| 90 | + edgecolor=INK_SOFT, |
| 91 | +) |
| 92 | +for text in legend.get_texts(): |
| 93 | + text.set_color(INK) |
73 | 94 |
|
74 | | -plt.tight_layout() |
75 | | -plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
| 95 | +# Save |
| 96 | +plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG) |
0 commit comments