plotlet v0.6.2

scatter

Pairwise data

Minimal call

df = {"x": [1, 2, 3, 4, 5, 6, 7], "y": [2, 4, 3, 6, 5, 7, 6]}

c = pt.chart(df, aes(x="x", y="y"), xlabel="x", ylabel="y")
c.add_scatter(size=4)

Worked example

import math

import plotlet as pt
from plotlet import aes

raw = pt.load_dataset("penguins")
keep = [i for i in range(len(raw["species"]))
        if not math.isnan(raw["flipper_length_mm"][i])
        and not math.isnan(raw["body_mass_g"][i])]
df = {k: [raw[k][i] for i in keep]
      for k in ("species", "flipper_length_mm", "body_mass_g")}

c = pt.chart(df, aes(x="flipper_length_mm", y="body_mass_g",
                     color="species"),
             title="Palmer penguins",
             xlabel="flipper length (mm)", ylabel="body mass (g)",
             gridlines=True)
c.add_scatter(size=3, alpha=0.7)

Docstring

Scatter — single-series xy.

  c.add_scatter(aes(x="col_x", y="col_y"))                 # columns via aes
  c.add_scatter(aes(x="col_x", y="col_y"), color="red")    # literal color
  c.add_scatter(aes(..., color="group"))                   # categorical → palette
  c.add_scatter(aes(..., color="weight"))                  # numeric col → cmap
  c.add_scatter(aes(..., color="g", group="subject"))      # invisible finer split
  c.add_scatter(aes(..., alpha="cohort"),                  # opacity per level
            alphas=(0.3, 1.0))
  c.add_scatter(aes(...), size=3)                          # fixed marker radius (px)
  c.add_scatter(aes(..., size="mass"), sizes=(2, 7))       # graded per-point radius
  c.add_scatter(aes(..., style="group"))                   # per-level marker glyph
  c.add_scatter(aes(...), rasterize=True)                  # force dots → one <image>
                                                           # (auto above the point threshold)

`color="red"` (bare) is always a literal color. `aes(color="col")` maps
the column: all-numeric values → continuous cmap (cmap/vmin/vmax/norm),
any non-numeric value → categorical palette.
To force a numeric column to be treated as categorical, cast to strings
first: `df["clusters"] = df["clusters"].astype(str)`.

Column-driven categorical splitting (`color`/`group`/`alpha` in aes) is handled
at the Chart layer — the artist itself always sees one series per record.
`size`/`style` are computed per-point and stay inside a single record.
Continuous color is single-record-only — `group`/`alpha` column splits
are dropped on that path.