Global Defaults — dm.config¶
dm.config is the process-wide singleton that holds dartwork-mpl’s
behaviour toggles. Set it once near the top of your program (or in a
notebook’s first cell) and every subsequent call across dm.layout,
dm.io, and friends honours the new default — no need to thread the
keyword through every call site.
Per-call overrides always win. Passing simple_layout(fig, adopt_orphan_tick_font=True) overrides whatever you set on
dm.config. The singleton supplies the fallback only.
What’s in there¶
dm.config is a @dataclass with named fields. Today there are two;
more land as audit findings ship.
Field |
Default |
Affects |
|---|---|---|
|
|
|
|
|
Same three call sites. When |
The full surface is in config.py — that’s the SSOT, this page is the cookbook.
Patterns¶
1. Opt in project-wide¶
Set once near the top of your entry script or notebook. Every
simple_layout / save_formats / save_and_show call afterwards
picks it up.
import matplotlib.pyplot as plt
import dartwork_mpl as dm
# This project prefers orphan ticks to use the axis-label font.
dm.config.adopt_orphan_tick_font = True
dm.style.use("scientific")
fig, ax = plt.subplots(figsize=dm.figsize("13cm", "standard"))
ax.plot([1, 2, 3], [1, 4, 9])
dm.simple_layout(fig) # tick fonts adopted (config wins)
dm.save_formats(fig, "out", formats=("png", "svg"))
2. Scope the change to a with block¶
dm.config.override(...) restores the previous values on exit, even
on exception. Use this when most of your code wants the default but
one specific export needs the opposite.
with dm.config.override(adopt_orphan_tick_font=True):
dm.simple_layout(fig) # adoption ON here
dm.save_formats(fig, "press_release", formats=("pdf",))
dm.simple_layout(fig) # back to OFF
The block is exception-safe — raising inside still restores every overridden field.
3. Per-call override beats config¶
Pass the keyword explicitly when you want to bypass dm.config for a
single call. Anything you pass (True or False) wins; the only
value that defers to dm.config is None (the call-site default).
dm.config.adopt_orphan_tick_font = True # project default
# Just this figure: skip adoption.
dm.simple_layout(fig, adopt_orphan_tick_font=False)
4. Debug surprise tick changes¶
When a tick font silently changes between two draws (a common
constrained-layout / re-layout hazard), turn the warning on. Every
adoption emits a UserWarning that includes the axis it touched, so
you can isolate the offender.
import warnings
dm.config.warn_on_orphan_tick_adoption = True
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
dm.simple_layout(fig)
for w in caught:
print(w.message)
# UserWarning: orphan-tick font adoption mutated 2 axes ...
Pair with dm.config.adopt_orphan_tick_font = False and the warning
goes silent — confirming you’ve fully opted out.
5. Typos fail loudly¶
override(...) raises AttributeError for any field name that isn’t
declared on Config. A typo can’t silently shadow the singleton.
try:
with dm.config.override(adopt_orphn_tick_font=False): # typo
...
except AttributeError as exc:
print(exc)
# dm.config has no attribute(s): ['adopt_orphn_tick_font']. Known fields: ...
Use this to your advantage: when you suspect a stale doc, just try the field name — if it fails, the field’s gone or never existed.
Mental model¶
flowchart TD
A["<b>① per-call keyword</b><br/><code>simple_layout(fig, adopt_orphan_tick_font=False)</code><br/><i>highest priority — always wins</i>"]
B["<b>② dm.config field</b><br/><code>dm.config.adopt_orphan_tick_font = False</code><br/><i>project-wide default</i>"]
C["<b>③ hard-coded Config default</b><br/><code>False</code><br/><i>library fallback</i>"]
A -->|"keyword is None → fall through"| B
B -->|"field unset → fall through"| C
style A fill:#fef3c7,stroke:#f0c000,stroke-width:1.5px,color:#1c2024
style B fill:#ecfeff,stroke:#7cd4e0,stroke-width:1px,color:#1c2024
style C fill:#f3e8ff,stroke:#c4a0e8,stroke-width:1px,color:#1c2024
The chain is deterministic and read-only at the lower levels —
the per-call keyword never mutates dm.config, and dm.config never
mutates the dataclass defaults.
When to add a new field¶
For library contributors — most users can skip this section; it’s about
proposing a new dm.config field, not using the existing ones.
Don’t reach for dm.config for everything. Use it when:
The toggle is a bool / enum default the user might want to flip for a whole project, not a per-call decision.
There’s no preset-level home for it (preset attributes are for style,
dm.configis for behaviour).The current default is silent — i.e., users today have no knob, and one would help.
Skip it when:
The setting belongs to a preset (
dm.style.use(...)).The setting is truly call-site (file paths, individual figure options).
The roadmap of candidate fields is tracked at issue #311 (B19 — config audit).
See also¶
Layout and Typography — where
adopt_orphan_tick_fontactually fires.Save and Validation —
save_formats/save_and_showread the same field.dm.dpi(n)— the DPI ladder (preset’s basesavefig.dpi+n × 50) that pairs naturally with these defaults. With the presets now shipping300as base,dm.dpi()returns300.0,dm.dpi(1)returns350.0, etc.