set_up_tabular_legend

mdhelper.plot.axis.set_up_tabular_legend(rows: list[str], cols: list[str], *, hlabel: str = None, vlabel: str = None, hla: str = 'left', vla: str = 'top', condense: bool = False, **kwargs) tuple[dict[str, Any], int, int][source]

Sets up a tabular legend for a matplotlib.axes.Axes object.

Parameters:
rowstuple or list

Raw string representations of the row values.

colstuple or list

Raw string representations of the column values.

hlabelstr, keyword-only, optional

Horizontal label for column values.

vlabelstr, keyword-only, optional

Vertical label for row values.

hlastr, keyword-only, default: "left"

Alignment for hlabel.

Valid values:

  • "left": Left-aligned text.

  • "center": Horizontally centered text.

vlastr, keyword-only, default: "top"

Alignment for vlabel.

Valid values:

  • "top": Top-aligned text.

  • "center": Vertically centered text.

condensebool, keyword-only, default: False

Condenses the legend by placing vlabel in the empty top-left corner. Cannot be used when no vlabel is specified or in conjuction with vla="center" (which will take priority).

**kwargs

Keyword arguments passed to matplotlib.axes.Axes.legend().

Returns:
propertiesdict

Properties of the tabular legend to be unpacked and used in the matplotlib.axes.Axes.legend() call.

nrowint

Number of rows in the legend.

idx_startint

Index at which to start storing handles for matplotlib.artist objects.

Notes

Condensing the legend can cause alignment issues in the first column containing the row values if the row values are not of comparable length to the rows label. An easy but imprecise fix is to center the shorter values using the width of the largest matplotlib.transforms.Bbox in the first column. Sample code for use in your main script utilizing the outputs of this function is provided below:

(props, nrow, start) = tabular_legend(..., handletextpad=-5/4)
fig, ax = plt.subplots(...)
for i, x in enumerate(...):
    for j, y in enumerate(...):
        props["handles"][start + i * nrow + j], = ax.plot(...)
ax.set_xlabel(...)
ax.set_ylabel(...)
lgd = ax.legend(**props)
fig.canvas.draw()
texts = lgd.get_texts()[:nrow]
bounds = [t.get_window_extent().bounds[2] / 2 for t in texts]
center = max(bounds)
for k, t in enumerate(texts):
    t.set_position((center - bounds[k], 0))
plt.show()