Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add title_kw to legend and fix titlefontweight/titlefontcolor
The legend API now accepts a title_kw dict for passing arbitrary Text
properties to the legend title (e.g. title_kw={'style': 'italic'}),
consistent with the existing handle_kw parameter for handle styling.
This change also fixes a pre-existing bug where titlefontweight and
titlefontcolor were accepted by the API and silently stored but never
actually applied to the legend title Text object — they now take effect
as expected.
  • Loading branch information
cvanelteren committed Mar 23, 2026
commit 44ae174df69e3d7502674e34fc0c226c8a993716
6 changes: 6 additions & 0 deletions ultraplot/axes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,10 @@
titlefontsize, titlefontweight, titlefontcolor : optional
The font size, weight, and color for the legend title. Font size is interpreted
by `~ultraplot.utils.units`. The default size is `fontsize`.
title_kw : dict-like, optional
Additional properties passed to the legend title text object, e.g.
``title_kw={'style': 'italic'}``. This can be used to set any
`~matplotlib.text.Text` property on the legend title.
borderpad, borderaxespad, handlelength, handleheight, handletextpad, labelspacing, columnspacing : unit-spec, optional
Various matplotlib `~matplotlib.axes.Axes.legend` spacing arguments.
%(units.em)s
Expand Down Expand Up @@ -1231,6 +1235,7 @@ def _add_legend(
titlefontsize=None,
titlefontweight=None,
titlefontcolor=None,
title_kw=None,
handle_kw=None,
handler_map=None,
span: Optional[Union[int, Tuple[int, int]]] = None,
Expand Down Expand Up @@ -1263,6 +1268,7 @@ def _add_legend(
titlefontsize=titlefontsize,
titlefontweight=titlefontweight,
titlefontcolor=titlefontcolor,
title_kw=title_kw,
handle_kw=handle_kw,
handler_map=handler_map,
span=span,
Expand Down
27 changes: 23 additions & 4 deletions ultraplot/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,7 @@ class _LegendInputs:
titlefontsize: float
titlefontweight: Any
titlefontcolor: Any
title_kw: Any
handle_kw: Any
handler_map: Any
span: Optional[Union[int, Tuple[int, int]]]
Expand Down Expand Up @@ -1794,6 +1795,7 @@ def _resolve_inputs(
titlefontsize=None,
titlefontweight=None,
titlefontcolor=None,
title_kw=None,
handle_kw=None,
handler_map=None,
span: Optional[Union[int, Tuple[int, int]]] = None,
Expand Down Expand Up @@ -1844,6 +1846,7 @@ def _resolve_inputs(
titlefontsize=titlefontsize,
titlefontweight=titlefontweight,
titlefontcolor=titlefontcolor,
title_kw=title_kw,
handle_kw=handle_kw,
handler_map=handler_map,
span=span,
Expand Down Expand Up @@ -1896,6 +1899,9 @@ def _resolve_style_kwargs(
lax,
fontcolor,
fontweight,
titlefontweight,
titlefontcolor,
title_kw,
handle_kw,
kwargs,
):
Expand All @@ -1908,10 +1914,16 @@ def _resolve_style_kwargs(
kw_text["color"] = fontcolor
if fontweight is not None:
kw_text["weight"] = fontweight
kw_title = {}
if titlefontweight is not None:
kw_title["weight"] = titlefontweight
if titlefontcolor is not None:
kw_title["color"] = titlefontcolor
kw_title.update(title_kw or {})
kw_handle = _pop_props(kwargs, "line")
kw_handle.setdefault("solid_capstyle", "butt")
kw_handle.update(handle_kw or {})
return kw_frame, kw_text, kw_handle, kwargs
return kw_frame, kw_text, kw_title, kw_handle, kwargs

def _build_legends(
self,
Expand Down Expand Up @@ -1959,12 +1971,14 @@ def _build_legends(
lax.add_artist(obj)
return objs

def _apply_handle_styles(self, objs, *, kw_text, kw_handle):
def _apply_handle_styles(self, objs, *, kw_text, kw_title, kw_handle):
"""
Apply per-handle styling overrides to legend artists.
"""
for obj in objs:
obj.set_clip_on(False)
if kw_title:
obj.get_title().update(kw_title)
box = getattr(obj, "_legend_handle_box", None)
for child in guides._iter_children(box):
if isinstance(child, mtext.Text):
Expand Down Expand Up @@ -2015,6 +2029,7 @@ def add(
titlefontsize=None,
titlefontweight=None,
titlefontcolor=None,
title_kw=None,
handle_kw=None,
handler_map=None,
span: Optional[Union[int, Tuple[int, int]]] = None,
Expand Down Expand Up @@ -2050,6 +2065,7 @@ def add(
titlefontsize=titlefontsize,
titlefontweight=titlefontweight,
titlefontcolor=titlefontcolor,
title_kw=title_kw,
handle_kw=handle_kw,
handler_map=handler_map,
span=span,
Expand All @@ -2062,10 +2078,13 @@ def add(

lax, kwargs = self._resolve_axes_layout(inputs)

kw_frame, kw_text, kw_handle, kwargs = self._resolve_style_kwargs(
kw_frame, kw_text, kw_title, kw_handle, kwargs = self._resolve_style_kwargs(
lax=lax,
fontcolor=inputs.fontcolor,
fontweight=inputs.fontweight,
titlefontweight=inputs.titlefontweight,
titlefontcolor=inputs.titlefontcolor,
title_kw=inputs.title_kw,
handle_kw=inputs.handle_kw,
kwargs=kwargs,
)
Expand All @@ -2079,5 +2098,5 @@ def add(
kwargs=kwargs,
)

self._apply_handle_styles(objs, kw_text=kw_text, kw_handle=kw_handle)
self._apply_handle_styles(objs, kw_text=kw_text, kw_title=kw_title, kw_handle=kw_handle)
return self._finalize(objs, loc=inputs.loc, align=inputs.align)