Skip to content

Commit 29b5379

Browse files
feat(makie): implement scatter-categorical
1 parent 77ea021 commit 29b5379

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

  • plots/scatter-categorical/implementations/julia
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# anyplot.ai
2+
# scatter-categorical: Categorical Scatter Plot
3+
# Library: Makie.jl 0.21 | Julia 1.11
4+
# Quality: pending | Created: 2026-09-05
5+
6+
using CairoMakie
7+
using Colors
8+
using Random
9+
10+
Random.seed!(42)
11+
12+
# --- Theme tokens ------------------------------------------------------------
13+
const THEME = get(ENV, "ANYPLOT_THEME", "light")
14+
const PAGE_BG = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17"
15+
const INK = THEME == "light" ? colorant"#1A1A17" : colorant"#F0EFE8"
16+
const INK_SOFT = THEME == "light" ? colorant"#4A4A44" : colorant"#B8B7B0"
17+
const IMPRINT_PALETTE = [
18+
colorant"#009E73", colorant"#C475FD", colorant"#4467A3", colorant"#BD8233",
19+
colorant"#AE3030", colorant"#2ABCCD", colorant"#954477", colorant"#99B314",
20+
]
21+
22+
# --- Data ---------------------------------------------------------------------
23+
# Soil nutrient survey across three land-use types: fertilized cropland runs
24+
# nitrogen-rich, grassland sits in between, and undisturbed forest soil is
25+
# nutrient-poor but more variable plot to plot.
26+
land_uses = ["Cropland", "Grassland", "Forest"]
27+
n_means = [45.0, 26.0, 12.0]
28+
n_sds = [6.0, 5.0, 4.5]
29+
p_means = [31.0, 19.0, 8.0]
30+
p_sds = [4.5, 4.0, 3.5]
31+
n_samples = 60
32+
markers = [:circle, :utriangle, :diamond]
33+
34+
nitrogen = Float64[]
35+
phosphorus = Float64[]
36+
group_idx = Int[]
37+
38+
for i in eachindex(land_uses)
39+
append!(nitrogen, n_means[i] .+ n_sds[i] .* randn(n_samples))
40+
append!(phosphorus, p_means[i] .+ p_sds[i] .* randn(n_samples) .+ 0.3 .* (nitrogen[end-n_samples+1:end] .- n_means[i]))
41+
append!(group_idx, fill(i, n_samples))
42+
end
43+
44+
title_str = "scatter-categorical · julia · makie · anyplot.ai"
45+
46+
# --- Plot ----------------------------------------------------------------------
47+
fig = Figure(
48+
resolution = (1600, 900),
49+
fontsize = 14,
50+
backgroundcolor = PAGE_BG,
51+
)
52+
53+
ax = Axis(
54+
fig[1, 1];
55+
title = title_str,
56+
titlesize = 20,
57+
titlecolor = INK,
58+
xlabel = "Soil Nitrogen (mg/kg)",
59+
ylabel = "Soil Phosphorus (mg/kg)",
60+
xlabelsize = 14,
61+
ylabelsize = 14,
62+
xlabelcolor = INK,
63+
ylabelcolor = INK,
64+
xticklabelsize = 12,
65+
yticklabelsize = 12,
66+
xticklabelcolor = INK_SOFT,
67+
yticklabelcolor = INK_SOFT,
68+
xtickcolor = INK_SOFT,
69+
ytickcolor = INK_SOFT,
70+
backgroundcolor = PAGE_BG,
71+
topspinevisible = false,
72+
rightspinevisible = false,
73+
leftspinecolor = INK_SOFT,
74+
bottomspinecolor = INK_SOFT,
75+
xgridcolor = RGBAf(INK.r, INK.g, INK.b, 0.15),
76+
ygridcolor = RGBAf(INK.r, INK.g, INK.b, 0.15),
77+
xminorgridvisible = false,
78+
yminorgridvisible = false,
79+
)
80+
81+
for i in eachindex(land_uses)
82+
mask = group_idx .== i
83+
scatter!(ax, nitrogen[mask], phosphorus[mask];
84+
color = IMPRINT_PALETTE[i], marker = markers[i],
85+
markersize = 16, strokewidth = 1, strokecolor = PAGE_BG,
86+
label = land_uses[i])
87+
end
88+
89+
axislegend(ax, position = :rb, labelcolor = INK, framevisible = false, labelsize = 13)
90+
91+
# --- Save -----------------------------------------------------------------------
92+
save("plot-$(THEME).png", fig; px_per_unit = 2)

0 commit comments

Comments
 (0)