plotlet v0.6.2

2. Aesthetics & scales

Column mappings versus literals, controlling axes, and everything about ticks. Every snippet on this page is executed on every build — the figures are its output.

Mapped vs. literal aesthetics

Name a column inside aes(...) and the aesthetic is mapped — plotlet builds a scale and a legend entry per level. Pass the same aesthetic as a bare kwarg and it is a literal that applies to every mark. The spelling decides: aes(color="species") maps the column, color="#534AB7" is just that color — even if a column shares the name.

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

left = pt.chart(df, aes(x="flipper_length_mm", y="body_mass_g"),
                title="mapped", legend=True,
                data_width=240, data_height=180)
left.add_scatter(aes(color="species"), size=2.5, alpha=0.7)

right = pt.chart(df, aes(x="flipper_length_mm", y="body_mass_g"),
                 title="literal", data_width=240, data_height=180)
right.add_scatter(color="#534AB7", size=2.5, alpha=0.5)

c = left | right

Size and style channels

Beyond position and color, columns can drive marker size — the radius in px (aes(size=...), with sizes=(lo, hi) on the artist to bound the range) — and marker shape (aes(style=...)). Channels compose — one column each.

import random
rng = random.Random(2)
n = 36
df = {"x": [rng.uniform(0, 10) for _ in range(n)],
      "y": [rng.uniform(0, 10) for _ in range(n)],
      "mass": [rng.uniform(5, 50) for _ in range(n)],
      "group": [["alpha", "beta", "gamma"][i % 3] for i in range(n)]}

c = pt.chart(df, aes(x="x", y="y", size="mass",
                     color="group", style="group"),
             title="color + size + style", xlabel="x", ylabel="y",
             legend=True, data_width=400, data_height=240)
c.add_scatter(sizes=(2, 8))

Categorical order

Categorical axes default to first-seen order. xscale("category", order=[...]) pins the order you mean.

tips = pt.load_dataset("tips")

c = pt.chart(tips, aes(x="day", y="tip"), ylabel="tip ($)")
c.xscale("category", order=["Thur", "Fri", "Sat", "Sun"])
c.add_boxplot()
["Thur","Fri","Sat","Sun"]

Log scales

xscale("log") / yscale("log") switch an axis to log10. The power10 tick formatter writes exponents properly.

xs = [1, 3, 10, 30, 100, 300, 1000, 3000, 10000]
df = {"x": xs, "y": [x ** 0.5 for x in xs]}

c = pt.chart(df, aes(x="x", y="y"), xlabel="dose", ylabel="response",
             gridlines=True)
c.xscale("log")
c.xticks(format="power10")
c.add_line()
c.add_scatter(size=3)

Limits

Axes autoscale to the data with a small expansion so extremes don’t sit on the frame. xlim= / ylim= (as chart kwargs or method calls) pin exact ranges.

import math
xs = [i * 0.2 for i in range(60)]
df = {"x": xs, "y": [0.5 + 0.6 * math.sin(x) for x in xs]}

c = pt.chart(df, aes(x="x", y="y"),
             title="ylim=(0, 1) clamps the frame",
             ylim=(0, 1), data_width=380, data_height=160)
c.add_line()

Tick control

xticks / yticks take a list of positions (empty list hides the axis entirely), plus rotation=, side= (“top” / “right”), direction="in", and marks=False / labels=False to hide marks or labels independently.

import math
xs = [i * 0.2 for i in range(40)]
df = {"x": xs, "y": [math.sin(x) for x in xs]}

c = pt.chart(df, aes(x="x", y="y"), data_width=380, data_height=170,
             title="ticks: explicit positions, rotated, right side")
c.add_line()
c.xticks([0, math.pi, 2 * math.pi], rotation=45)
c.yticks(side="right")

Tick formatters

Named formatters — comma, money, percent, si, scientific, power10 — attach per axis with format=. Register your own with pt.register_formatter.

df = {"quarter": ["Q1", "Q2", "Q3", "Q4"],
      "revenue": [1_200_000, 1_850_000, 1_600_000, 2_400_000]}

c = pt.chart(df, aes(x="quarter", y="revenue"), title="revenue",
             data_width=340, data_height=180)
c.add_bar(fill="#4C72B0")
c.yticks(format="si")
["Q1","Q2","Q3","Q4"]

Gridlines and spines

gridlines=True draws the dotted grid. c.spines(top=False, right=False) drops frame sides for the open look.

import math
xs = [i * 0.2 for i in range(40)]
df = {"x": xs, "y": [math.sin(x) for x in xs]}

c = pt.chart(df, aes(x="x", y="y"), gridlines=True,
             data_width=380, data_height=170,
             title="open frame + grid")
c.spines(top=False, right=False)
c.add_line()

← Introduction  ·  Titles, labels & legends →