|
1 | 1 | """ anyplot.ai |
2 | 2 | scatter-basic: Basic Scatter Plot |
3 | 3 | Library: altair 6.1.0 | Python 3.14.4 |
4 | | -Quality: 88/100 | Created: 2026-04-23 |
| 4 | +Quality: 89/100 | Updated: 2026-04-23 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import importlib |
|
21 | 21 | PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
22 | 22 | INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
23 | 23 | INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" |
24 | | -BRAND = "#009E73" |
| 24 | +INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F" |
| 25 | +BRAND = "#009E73" # Okabe-Ito position 1 |
25 | 26 |
|
26 | | -# Data |
| 27 | +# Data — study hours vs. exam scores (r ~ 0.75) |
27 | 28 | np.random.seed(42) |
28 | 29 | n = 180 |
29 | 30 | study_hours = np.random.uniform(1, 12, n) |
30 | | -exam_scores = np.clip(40 + study_hours * 4.8 + np.random.randn(n) * 7.5, 30, 100) |
| 31 | +exam_scores = np.clip(38 + study_hours * 4.8 + np.random.normal(0, 7.0, n), 30, 100) |
31 | 32 | df = pd.DataFrame({"hours": study_hours, "score": exam_scores}) |
32 | 33 |
|
| 34 | +pearson_r = float(np.corrcoef(df["hours"], df["score"])[0, 1]) |
| 35 | + |
33 | 36 | # Plot |
34 | 37 | points = ( |
35 | 38 | alt.Chart(df) |
36 | | - .mark_circle(size=180, opacity=0.7, color=BRAND, stroke=PAGE_BG, strokeWidth=0.8) |
| 39 | + .mark_circle(size=170, opacity=0.7, color=BRAND, stroke=PAGE_BG, strokeWidth=0.8) |
37 | 40 | .encode( |
38 | | - x=alt.X("hours:Q", title="Study Hours per Week", scale=alt.Scale(domain=[0, 13], nice=False)), |
39 | | - y=alt.Y("score:Q", title="Exam Score (%)", scale=alt.Scale(domain=[25, 105], nice=False)), |
| 41 | + x=alt.X( |
| 42 | + "hours:Q", |
| 43 | + title="Study Hours per Week", |
| 44 | + scale=alt.Scale(domain=[0, 13], nice=False), |
| 45 | + axis=alt.Axis(tickCount=6, ticks=False, labelPadding=10, titlePadding=18), |
| 46 | + ), |
| 47 | + y=alt.Y( |
| 48 | + "score:Q", |
| 49 | + title="Exam Score (%)", |
| 50 | + scale=alt.Scale(domain=[25, 105], nice=False), |
| 51 | + axis=alt.Axis(tickCount=8, ticks=False, labelPadding=10, titlePadding=18), |
| 52 | + ), |
| 53 | + tooltip=[ |
| 54 | + alt.Tooltip("hours:Q", title="Study hrs / wk", format=".1f"), |
| 55 | + alt.Tooltip("score:Q", title="Exam %", format=".1f"), |
| 56 | + ], |
40 | 57 | ) |
| 58 | + .interactive() |
41 | 59 | ) |
42 | 60 |
|
43 | 61 | chart = ( |
|
47 | 65 | background=PAGE_BG, |
48 | 66 | title=alt.Title( |
49 | 67 | "scatter-basic · altair · anyplot.ai", |
| 68 | + subtitle=f"n = {n} · Pearson r = {pearson_r:.2f}", |
50 | 69 | fontSize=28, |
51 | 70 | fontWeight="normal", |
52 | 71 | color=INK, |
| 72 | + subtitleFontSize=16, |
| 73 | + subtitleColor=INK_MUTED, |
| 74 | + subtitlePadding=6, |
53 | 75 | anchor="start", |
54 | | - offset=16, |
| 76 | + offset=20, |
55 | 77 | ), |
56 | 78 | ) |
57 | 79 | .configure_view(fill=PAGE_BG, stroke=None) |
58 | 80 | .configure_axis( |
59 | 81 | labelFontSize=18, |
60 | 82 | titleFontSize=22, |
61 | | - titlePadding=14, |
| 83 | + titleFontWeight="normal", |
62 | 84 | domainColor=INK_SOFT, |
| 85 | + domainWidth=0.9, |
63 | 86 | tickColor=INK_SOFT, |
64 | 87 | gridColor=INK, |
65 | 88 | gridOpacity=0.10, |
|
0 commit comments