|
1 | | -""" pyplots.ai |
| 1 | +"""pyplots.ai |
2 | 2 | line-retention-cohort: User Retention Curve by Cohort |
3 | 3 | Library: seaborn 0.13.2 | Python 3.14.3 |
4 | 4 | Quality: 84/100 | Created: 2026-03-16 |
|
33 | 33 |
|
34 | 34 | df = pd.DataFrame(records) |
35 | 35 |
|
36 | | -# Plot |
37 | | -palette = ["#8FAABC", "#7B9EA8", "#306998", "#2A7F62", "#1B9E77"] |
38 | | -linewidths = [1.8, 2.0, 2.5, 2.8, 3.2] |
| 36 | +# Plot - use seaborn style, context, and hue-based grouping |
| 37 | +sns.set_theme( |
| 38 | + style="whitegrid", |
| 39 | + rc={ |
| 40 | + "axes.spines.top": False, |
| 41 | + "axes.spines.right": False, |
| 42 | + "grid.alpha": 0.15, |
| 43 | + "grid.linewidth": 0.8, |
| 44 | + "axes.grid.axis": "y", |
| 45 | + }, |
| 46 | +) |
| 47 | +sns.set_context("talk", font_scale=1.1) |
| 48 | + |
| 49 | +palette = sns.color_palette("colorblind", n_colors=5) |
39 | 50 |
|
40 | 51 | fig, ax = plt.subplots(figsize=(16, 9)) |
41 | 52 |
|
42 | | -for i, cohort_label in enumerate(df["cohort"].unique()): |
43 | | - cohort_data = df[df["cohort"] == cohort_label] |
44 | | - sns.lineplot( |
45 | | - data=cohort_data, |
46 | | - x="week", |
47 | | - y="retention", |
48 | | - label=cohort_label, |
49 | | - color=palette[i], |
50 | | - linewidth=linewidths[i], |
51 | | - marker="o", |
52 | | - markersize=6 + i, |
53 | | - ax=ax, |
54 | | - ) |
55 | | - |
56 | | -ax.axhline(y=20, color="#999999", linestyle="--", linewidth=1.2, alpha=0.6) |
57 | | -ax.text(12.2, 20, "20% target", fontsize=13, color="#999999", va="center") |
| 53 | +sns.lineplot( |
| 54 | + data=df, |
| 55 | + x="week", |
| 56 | + y="retention", |
| 57 | + hue="cohort", |
| 58 | + style="cohort", |
| 59 | + markers=True, |
| 60 | + dashes=False, |
| 61 | + palette=palette, |
| 62 | + linewidth=2.5, |
| 63 | + markersize=8, |
| 64 | + ax=ax, |
| 65 | +) |
| 66 | + |
| 67 | +cohort_labels = df["cohort"].unique() |
| 68 | +for i, line in enumerate(ax.lines[: len(cohort_labels)]): |
| 69 | + weight = 1.5 + i * 0.4 |
| 70 | + line.set_linewidth(weight) |
| 71 | + line.set_markersize(5 + i * 1.5) |
| 72 | + line.set_alpha(0.5 + i * 0.12) |
| 73 | + |
| 74 | +ax.axhline(y=20, color="#888888", linestyle="--", linewidth=1.2, alpha=0.5, zorder=1) |
| 75 | +ax.text(12.3, 20, "20% target", fontsize=13, color="#888888", va="center", fontstyle="italic") |
58 | 76 |
|
59 | 77 | # Style |
60 | 78 | ax.set_title("line-retention-cohort · seaborn · pyplots.ai", fontsize=24, fontweight="medium", pad=20) |
|
66 | 84 | ax.set_ylim(0, 105) |
67 | 85 | ax.set_xticks(weeks) |
68 | 86 |
|
69 | | -ax.spines["top"].set_visible(False) |
70 | | -ax.spines["right"].set_visible(False) |
71 | | -ax.yaxis.grid(True, alpha=0.2, linewidth=0.8) |
72 | | - |
73 | | -ax.legend(fontsize=14, frameon=False, loc="upper right", title="Signup Cohort", title_fontsize=15) |
| 87 | +legend = ax.legend(fontsize=14, frameon=False, loc="upper right", title="Signup Cohort", title_fontsize=15) |
| 88 | +legend.get_title().set_fontweight("semibold") |
74 | 89 |
|
75 | 90 | plt.tight_layout() |
76 | 91 | plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
0 commit comments