Skip to content

UltraPlot v2.5.0: Hawkeye, text-alignment, and latex fonts

Latest

Choose a tag to compare

@cvanelteren cvanelteren released this 22 Jul 23:15
· 4270 commits to main since this release

In UltraPlot 2.5.0, we introduce the Hawkeye feature for GeoAxes, a new automatic text-alignment feature, and the ability to change latex fonts with more control.

New Features

  • Hawkeye map insets (GeoAxes.hawkeye): Added a geographic callout inset
    that draws attention to a region of a map without inheriting the parent
    projection's aspect. Regular insets follow the parent projection, so Cartopy
    stretches them to whatever the projection dictates; a hawkeye instead lets you
    request a square — or circular — locator map, anchored anywhere on the parent
    axes, with an automatically drawn indicator box and optional connectors.
    Hawkeyes are excluded from automatic layout, so they can extend past the parent
    axes without reserving subplot space, and the returned object is an ordinary
    GeoAxes you can draw external geospatial data into.
hawkeye_preview
snippet
import ultraplot as uplt

singapore = (103.8198, 1.3521)
fig, ax = uplt.subplots(proj="robin", refwidth=4)
ax.format(land=True, landcolor="gray8", oceancolor="blue9")
ax.plot(*singapore, marker="o", color="red", ms=5, transform="cyl")
ax.text(106, 4, "Singapore", color="red", size=7, transform="map")

# A circular locator map anchored to the upper-right corner
inax = ax.hawkeye(
    (0.97, 0.97),
    size=0.23,
    anchor="ur",
    proj="merc",
    extent=(103.76, 103.90, 1.27, 1.41),
    shape="circle",
    target="circle",
    connector="line",
    color="red",
    indicator_kw={"linewidth": 1.5},
)
inax.format(land=True, landcolor="gray9", oceancolor="blue9")
inax.plot(*singapore, marker="o", color="red", ms=5, transform="cyl")
  • Circular and aspect-aware insets: Generalized inset support so geographic
    insets can use a circular frame while still preserving projection scale. A new
    aspect-aware locator keeps a circular or square inset anchored to its
    lower-left corner after the box-aspect adjustment, so callout maps stay put
    under resizing. Rectangular frames preserve both the requested extent and the
    projection scale; circular frames expand the shorter projected dimension to
    keep the projection faithful (pass aspect='auto' to instead fit the exact
    extent with distortion).
circular_inset_preview
snippet
import ultraplot as uplt

fig, ax = uplt.subplots(proj="robin", refwidth=4)
ax.format(land=True, landcolor="gray8", oceancolor="blue9")

# `shape` controls the inset frame; `target` controls the indicator on the parent
inax = ax.hawkeye(
    (0.97, 0.97), size=0.23, anchor="ur", proj="merc",
    extent=(103.76, 103.90, 1.27, 1.41),
    shape="circle", target="circle", connectors="line",
)
inax.format(land=True, landcolor="gray9", oceancolor="blue9")
  • Automatic text alignment (Axes.auto_align_text): Added a KD-tree-based
    relaxation solver that repositions text and annotations so they stop
    overlapping each other, the plotted data, and the axes edges, then pulls them
    back toward where you put them. Because it runs at draw time, the layout stays
    valid across resizing and changing data limits. Opt individual labels in with
    avoid_overlap=True, enable it globally with the new text.align rc setting,
    and tune it with text.align.pad, text.align.maxiter, and
    text.align.arrows (which draws a connector back to each displaced label).
text_align_preview
snippet
import ultraplot as uplt

fig, ax = uplt.subplots()
ax.scatter(x, y)
for xi, yi, name in zip(x, y, names):
    ax.text(xi, yi, name)

# Relax the labels apart; `arrows=True` connects moved labels to their points
ax.auto_align_text(arrows=True)
  • Computer Modern math symbols (mathtext.cm_symbols): Added a middle ground
    between font-matched math and full text.usetex. With the setting on,
    ordinary letters and numbers keep the active document font, while \mathcal
    routes through cmsy10 and big operators (\sum, \prod, \int, \oint,
    \bigcup, \bigoplus) route through cmex10 for an authentic Computer Modern
    look — no external LaTeX required. Math is parsed when the figure is drawn,
    so set this globally rather than inside a context block.
cm_symbols_preview
snippet
import ultraplot as uplt

expr = r"$\mathcal{ABCXYZ}\quad\sum_{i=0}^{n}\quad\prod_{j=1}^{m}\quad\int_a^b\quad\oint_C$"

uplt.rc["mathtext.cm_symbols"] = True
fig, ax = uplt.subplots(refwidth=6, refheight=1.1)
ax.text(0.02, 0.5, expr, transform="axes", va="center", fontsize=24)
ax.format(title="Computer Modern math symbols", titleloc="left")
  • Geographic axes in mixed subplot layouts (abcanchor + geo aspect): Gave
    map users explicit control over the fixed-aspect-vs-slot trade-off that arises
    when a map shares a GridSpec with Cartesian axes. The new abcanchor option
    chooses whether an a-b-c label attaches to the visible map boundary
    ('axes', the default) or to the original GridSpec slot ('slot', useful for
    a regular label grid across mixed subplot types). Maps can also be stretched to
    fill their slot with aspect='auto', or made the figure's layout reference so
    the whole figure resizes around them.
geo_layout_preview
snippet
import ultraplot as uplt

layout = [[1, 1, 1, 2, 2, 2], [3, 3, 4, 4, 5, 5]]
fig, axs = uplt.subplots(layout, refwidth=2.4, proj={4: "cyl"}, share=False)
axs[3].format(
    lonlim=(0, 1),
    latlim=(0, 1),
    abcanchor="slot",  # align the map's a-b-c label with the Cartesian slots
)
fig.format(abc="A.", abcloc="left")
  • Shared row/column label spacing: When figure-level row or column labels and
    a shared spanning axis label sit on the same side, the row/column labels are
    now placed nearer the axes and the spanning label outside them. The gap is
    controlled by the new leftlabel.sharedpad, rightlabel.sharedpad,
    bottomlabel.sharedpad, and toplabel.sharedpad settings, which can also be
    passed to format (e.g. fig.format(leftlabelsharedpad='2em')).

    snippet
    import ultraplot as uplt
    
    fig, axs = uplt.subplots(ncols=2, nrows=2, share=True, span=True)
    fig.format(
        leftlabels=("Row A", "Row B"),
        ylabel="shared y label",
        leftlabelsharedpad="2em",  # gap between the row labels and the spanning label
    )
  • Keyword-alias cleanup (_alias_kwargs): Extracted the keyword/alias
    resolution helpers out of the internals grab-bag into a dedicated
    internals/kwargs.py, and added an @_alias_kwargs decorator that folds
    synonym keywords into their canonical names with the same precedence and
    conflict warning as the old _not_none boilerplate. Figure.__init__ is the
    first adopter. As a user-visible upshot, the shared style docstrings (line,
    patch, pcolor/contour, text) now lead each numpydoc field with the canonical
    parameter name instead of a pile of aliases, making the parameter tables much
    easier to scan.

Bug Fixes

  • Title centering: Fixed the horizontal centering of titles (#766).
  • ListedColormap deprecation: Fixed a ListedColormap N deprecation
    warning from newer matplotlib (#769).
  • Cross-product deprecation: Fixed a deprecation in the cross-product
    computation (#777).

Maintenance & Internals

  • Deprecation cleanup: Removed deprecated items and unused imports (#763).
  • Docs: Simplified the docs and expanded the insets, projections, fonts, and
    subplots guides with the new features above.
  • History hygiene: Reverted a set of misplaced hawkeye commits from main
    before re-landing the feature cleanly (#772).

Commits

  • 83b0e73c8 [Feature] Add Hawkeye option (#771)
  • ceab2bfc4 Add circular inset options
  • 9175fafab [Feature] Text alignment (#754)
  • fa26deece Route selected mathtext glyphs to Computer Modern (#744)
  • 384a6259f [Feature] Abc anchor and Geo aspect (#767)
  • 8b174295b Reorder visual hierarchy when side-cap labels are given (#765)
  • 1be6eeacd Refactor/alias kwargs (#775)
  • 7a5ddfb5e Fix centering of titles (#766)
  • 4ab628987 Fix ListedColormap N deprecation (#769)
  • c3d1e2d7b Deprecation fix for cross product computation. (#777)
  • 410de735d Remove unused imports (#763)
  • 50cbc622f Remove deprecated items
  • 6e39447fc Simplify docs
  • d26943592 Revert misplaced hawkeye commits from main (#772)

What's Changed

Full Changelog: v2.4.1...v2.5.0