Plot Base Classes
Custom plots subclass BasePlot and implement run(self, benchmark_results). The chart helpers below build on BasePlot and add a create(...) method for common chart types, so most plots subclass one of them rather than BasePlot directly.
BasePlot
Bases: RegisterableComponent, ABC
Base interface for all plot components.
Subclasses should implement the run method.
run(benchmark_results: BenchmarkResultContainer, save_dir: str | None = None) -> None
abstractmethod
Generate plot output from benchmark results.
Parameters:
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data consumed by the plot implementation.
SeabornPlot
Base of a seaborn-oriented plot with a shared figure and axis configuration.
Every attribute below can be set when the plot is constructed, e.g.
RuntimePlot(figure=Figure(width=12, file_formats=("pgf", "png"))). The flat
spelling those options used to have - width=12 - is still accepted.
Attributes:
-
figure(Figure) –The figure this plot is drawn on and the files written from it - its size, resolution, output formats, and whether it is opened in a window.
-
theme(Theme | None) –The seaborn theme the figure is drawn under and the gridlines behind the marks. By default seaborn's
whitegridwith lines along the value axis;Nonefor matplotlib's own look, without a grid. -
missing(Missing) –What becomes of the values the plot cannot draw - an infinite time to solution, a metric that failed - and how the figure says they were there.
Requires
Install the 'pre-defined' extra: pip install luna-bench[pre-defined]
figure: Figure = Figure()
class-attribute
instance-attribute
The figure this plot is drawn on and the files written from it.
theme: Theme | None = Theme()
class-attribute
instance-attribute
The seaborn theme the figure is drawn under, and the gridlines behind the marks.
A figure is read against its axis, so it is drawn with the lines that make that
possible unless asked otherwise. None takes the theme and the grid away.
missing: Missing = Missing()
class-attribute
instance-attribute
What becomes of the values the plot cannot draw, and how it says they were there.
option_bundles: dict[str, type[OptionBundle]] = {'style': PlotStyle}
class-attribute
Constructor arguments that configure several fields at once, and the bundle each takes.
A style is spread over the bundle fields rather than stored, so a benchmark can
hand the same look to every plot while each keeps what it says itself. Applied least
specific first: the shared style, then a bundle passed to the plot, then a flat
option.
draw_into(axes: Axes, benchmark_results: BenchmarkResultContainer) -> None
Run this plot onto an existing axes rather than into a figure of its own.
Everything the plot draws goes through the pyplot state, so making that axes the current one is enough to redirect it. The figure, the files, and the window stay the caller's business - which is what lets several plots share one figure, e.g. the summary grid.
Parameters:
-
axes(Axes) –The axes to draw on.
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data handed to :meth:
run.
resolve_missing(df: pd.DataFrame, column: str, *, by: str | None = None, within: str | None = None) -> tuple[pd.DataFrame, dict[tuple[str, str], int]]
Return the drawable rows and how many of them were not, per category.
A metric with nothing to report says so with a None or an infinity - a time
to solution of a run that never reached the optimum is the usual one, since the
expected time to something that did not happen is unbounded. Neither is a height
a bar can have, and leaving them in poisons the aggregate: one infinity turns the
mean of an algorithm into an infinity, and a missing value silently shortens it.
What happens to them is :attr:missing, and by default it is nothing: the plot
raises rather than quietly showing a mean over fewer models than it claims. Asked
to carry on, it either leaves them out or fills them from the values that could be
drawn - Missing(policy="max") puts them just past the tallest bar, which is
where "worse than everything here" belongs. Either way they are counted and a
warning is logged: a bar resting on half its models is a different statement from
one resting on all of them, and that is not visible in the bar itself.
Parameters:
-
df(DataFrame) –The plotting data.
-
column(str) –Column holding the plotted value.
-
by(str | None, default:None) –Column whose categories the missing values are counted per, e.g. the x-axis of a bar plot. Without one they are counted under
"". -
within(str | None, default:None) –Column that splits those categories further, e.g. the grouping of a bar plot. Counting per group is what lets a figure mark the one bar of a group that lost values rather than the whole category it sits in.
Returns:
-
tuple[DataFrame, dict[tuple[str, str], int]]–The rows to draw, and the number of missing values per category and group - the group is
""where there is none. The mapping is empty when nothing was missing.
Raises:
-
PlotMissingValuesError–If values are missing and the policy is
"raise".
place_legend(axes: Axes, handles: list[Any] | None = None, labels: list[str] | None = None) -> None
Put the legend beside the axes, whatever drew it.
Outside the axes for a figure of its own: a legend inside sits on top of the data, and which corner is free depends on the run rather than on the plot - the figure would move its own key around as the numbers change. Beside it, the key is always in the same place and covers nothing.
A panel of someone else's figure is the exception. The room beside it belongs to the panel next to it, so a key anchored there is drawn over a neighbour rather than over the data; inside the panel it stays within the space the plot was given.
Parameters:
note_missing(handles: list[Any], labels: list[str], missing: dict[tuple[str, str], int]) -> None
Add the legend entry that says how many values the figure could not draw.
What a plot can say beyond that depends on what it draws. A bar has a slot of its
own to put a cross under, so BarPlot marks the categories themselves; a point in
a cloud or a step of a sweep has no slot, and the count in the key is the whole
statement there - enough that a filled value is not read as a measured one.
Parameters:
apply_theme() -> None
Install the seaborn theme this plot is drawn under, unless it has none.
The theme is matplotlib's global state rather than a property of one figure, so
it is installed before the figure is built and left in place afterwards: a
benchmark themes its plots by handing every one of them the same Theme, not by
each plot putting the previous look back.
apply_grid(axes: Axes) -> None
Draw the gridlines the theme asks for, behind everything else on axes.
Parameters:
-
axes(Axes) –The axes the plot was drawn on.
setup_figure() -> None
Create a matplotlib figure, unless the plot is drawing into a shared axes.
save_figure(save_dir: str) -> list[Path]
finalize_plot(xlabel: str, ylabel: str, title: str, ylim: tuple[float, float] | None = None, x_rotation: int = 45, save_dir: str | None = None) -> None
Apply common axis labels, title, limits, and display behavior.
Parameters:
-
xlabel(str) –Label for the x-axis.
-
ylabel(str) –Label for the y-axis.
-
title(str) –Plot title.
-
ylim(tuple[float, float] | None, default:None) –Lower and upper y-axis limits, by default
None. -
x_rotation(int, default:45) –Rotation angle for x-axis tick labels, by default
45. -
save_dir(str | None, default:None) –Directory to save the figure into, by default
None.
run(benchmark_results: BenchmarkResultContainer, save_dir: str | None = None) -> None
abstractmethod
Generate plot output from benchmark results.
Parameters:
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data consumed by the plot implementation.
BarPlot
Bases: SeabornPlot, ABC
Base helper for generating aggregated seaborn bar plots.
Subclasses turn benchmark results into row dictionaries and hand them to
:meth:create; everything below is shared configuration a user can set on any of
them at construction time, grouped into bundles by what it configures, e.g.
RuntimePlot(annotation=Annotation(enabled=False)). The flat spelling those
options used to have - annotate=False - is still accepted.
Attributes:
-
x(Dimension) –What the bars are - one per algorithm by default. Also titles the axis.
-
y(MetricDimension) –What the bars measure - the attribute read off each result, and its axis title.
-
aggregation(Aggregation) –Aggregation applied per x category, by default the mean over the models.
-
errorbars(ErrorBars) –The error bars drawn on top of the bars: what they show, their colour, and the caps that turn them into a T.
-
annotation(Annotation | None) –The values written above the bars, by default
None- none are written. -
grouping(Dimension | None) –What splits each bar into a group of bars:
ModelDimension,AlgorithmDimension,FeatureDimensionorParameterDimension.
Examples:
Split the bars by a per-model category and write the figure for LaTeX:
>>> plot = RuntimePlot(
... grouping=FeatureDimension(feature=UseCaseFeature, label="Use case"),
... figure=Figure(file_formats=("pgf", "png")),
... )
>>> bench.add_plot(name="runtime", plot=plot)
Requires
Install the 'pre-defined' extra: pip install luna-bench[pre-defined]
See Also
SeabornPlot : Figure size, output formats, and saving.
x: Dimension = AlgorithmDimension()
class-attribute
instance-attribute
What the bars are: one per value of this dimension, and its title on the axis.
y: MetricDimension = MetricDimension('value')
class-attribute
instance-attribute
What the bars measure: the attribute read off each result, and its title on the axis.
aggregation: Aggregation = Aggregation.MEAN
class-attribute
instance-attribute
Aggregation applied to the values of an x category, by default their mean.
errorbars: ErrorBars | None = ErrorBars()
class-attribute
instance-attribute
The error bars drawn on top of the bars: what they show, their colour and caps.
None draws none, the same as ErrorBars(spec=None).
annotation: Annotation | None = None
class-attribute
instance-attribute
The values written above the bars - how they are formatted and how large.
None, the default, writes none: a bar chart is read off its axis, and a number
above every bar is worth its clutter only when the exact value is the point. Pass an
Annotation to turn them on, empty for the defaults.
grouping: Dimension | None = None
class-attribute
instance-attribute
What splits each bar into a group of bars.
One of the groupers - ModelDimension, AlgorithmDimension, FeatureDimension,
ParameterDimension - or None, which leaves the bars ungrouped.
figure: Figure = Figure()
class-attribute
instance-attribute
The figure this plot is drawn on and the files written from it.
theme: Theme | None = Theme()
class-attribute
instance-attribute
The seaborn theme the figure is drawn under, and the gridlines behind the marks.
A figure is read against its axis, so it is drawn with the lines that make that
possible unless asked otherwise. None takes the theme and the grid away.
missing: Missing = Missing()
class-attribute
instance-attribute
What becomes of the values the plot cannot draw, and how it says they were there.
option_bundles: dict[str, type[OptionBundle]] = {'style': PlotStyle}
class-attribute
Constructor arguments that configure several fields at once, and the bundle each takes.
A style is spread over the bundle fields rather than stored, so a benchmark can
hand the same look to every plot while each keeps what it says itself. Applied least
specific first: the shared style, then a bundle passed to the plot, then a flat
option.
apply_grouping(benchmark_results: BenchmarkResultContainer, rows: list[dict[str, Any]]) -> dict[str, Any]
Split rows into groups along :attr:grouping.
What that means is the grouper's business - a column of the plotted data, a value looked up per model, or a setting the algorithms were configured with - and so is deciding that it does not apply, in which case the bars stay ungrouped.
Parameters:
-
benchmark_results(BenchmarkResultContainer) –Benchmark data the feature results and algorithm configurations are read from.
-
rows(list[dict[str, Any]]) –Row-oriented plot data, annotated - and, where a grouping applies to only part of the data, reduced - in place.
Returns:
draw(*, benchmark_results: BenchmarkResultContainer, rows: list[dict[str, Any]], save_dir: str | None = None, **overrides: Any) -> None
Group rows and draw them with the display configuration of this plot.
This is what turns the declared fields - :attr:x, :attr:title, :attr:hline
and the rest - into a :meth:create call, so a subclass only has to say which
rows it plots. Doing it in one place is also what keeps :attr:group_by working
for every bar plot rather than for those that remember to apply it.
Parameters:
-
benchmark_results(BenchmarkResultContainer) –Benchmark data, used to look up the groups of a feature :attr:
group_by. -
rows(list[dict[str, Any]]) –Row-oriented plot data.
-
save_dir(str | None, default:None) –Directory to save the figure into, by default
None. -
**overrides(Any, default:{}) –Keyword arguments forwarded to :meth:
create, overriding the fields.
transform_rows(rows: list[dict[str, Any]], x: str | None, group: str | None) -> list[dict[str, Any]]
Return the rows to plot, by default the rows as they are.
A subclass that has to reduce its rows before they are drawn - pooling counts
into a single ratio, say - overrides this rather than :meth:run, so it keeps
the shared grouping and display handling. It is told what the bars and the groups
turned out to be, since that is what a row has to keep to stay one of them.
Parameters:
-
rows(list[dict[str, Any]]) –Row-oriented plot data, already annotated with the dimensions' columns.
-
x(str | None) –Column the bars are drawn per, or
Nonewhen the plot has no rows. -
group(str | None) –Column the bars are split by, or
Nonewhen they are ungrouped.
Returns:
create(*, rows: list[dict[str, Any]], xlabel: str, ylabel: str, title: str, x: str = 'x', y: str = 'y', aggregation: Aggregation = Aggregation.MEAN, errorbar: ErrorBar | str = AUTO_ERRORBAR, hue: str | None = None, hline: float | None = None, hline_label: str | None = None, hcolor: str = REFERENCE_LINE_COLOUR, baseline: float | None = None, ylim: tuple[float, float] | None = None, legend: bool = False, save_dir: str | None = None, **kwargs: Any) -> None
Create a bar plot from row-oriented data.
Parameters:
-
rows(dict[str, Any]) –Row-oriented mapping used to construct the plotting DataFrame.
-
xlabel(str) –Label for the x-axis.
-
ylabel(str) –Label for the y-axis.
-
title(str) –Plot title.
-
x(str, default:'x') –Column name mapped to the x-axis, by default
"x". -
y(str, default:'y') –Column name mapped to the y-axis, by default
"y". -
aggregation(Aggregation, default:MEAN) –Aggregation strategy applied by seaborn, by default
Aggregation.MEAN. -
errorbar(ErrorBar | str, default:AUTO_ERRORBAR) –Seaborn error bar specification (
"sd",("ci", 95),Noneto disable). By default"auto", which takes the error bar from aggregation: the spread of the samples for means, none for min/max. -
hue(str | None, default:None) –Optional grouping column for grouped bars, by default
None. -
hline(float | None, default:None) –Optional horizontal reference line value, by default
None. -
hline_label(str | None, default:None) –Legend label for the horizontal reference line, by default
None. -
hcolor(str, default:REFERENCE_LINE_COLOUR) –Colour of the horizontal reference line, by default black.
-
baseline(float | None, default:None) –Height of a solid black baseline marking where the bars start, by default
None. Unlike hline it carries no label and stays out of the legend - it says where zero is, it does not name a target. -
ylim(tuple[float, float] | None, default:None) –Lower and upper y-axis limits, by default
None. -
legend(bool, default:False) –Whether seaborn should create a legend for hue groups, by default
False. -
save_dir(str | None, default:None) –Directory to save the figure into, by default
None. -
**kwargs(Any, default:{}) –Additional keyword arguments forwarded to :func:
seaborn.barplot. They override the defaults computed here, so anything seaborn understands (palette,saturation,capsize,err_kws, ...) can be tuned from the call site.
annotation_text(value: float) -> str
Return the text written above a bar of value.
Applies :attr:annotate_format, unless :attr:annotate_max_decimals allows the
value to be written as a plain decimal instead of in scientific notation. A value
read off a percent axis is written as a percentage, so the annotation says the
same thing as the axis it stands on - unless a format was asked for, which wins.
Parameters:
-
value(float) –The aggregated value of one bar.
Returns:
-
str–The annotation, e.g.
"0.000057"rather than"5.67e-05".
run(benchmark_results: BenchmarkResultContainer, save_dir: str | None = None) -> None
abstractmethod
Generate plot output from benchmark results.
Parameters:
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data consumed by the plot implementation.
draw_into(axes: Axes, benchmark_results: BenchmarkResultContainer) -> None
Run this plot onto an existing axes rather than into a figure of its own.
Everything the plot draws goes through the pyplot state, so making that axes the current one is enough to redirect it. The figure, the files, and the window stay the caller's business - which is what lets several plots share one figure, e.g. the summary grid.
Parameters:
-
axes(Axes) –The axes to draw on.
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data handed to :meth:
run.
resolve_missing(df: pd.DataFrame, column: str, *, by: str | None = None, within: str | None = None) -> tuple[pd.DataFrame, dict[tuple[str, str], int]]
Return the drawable rows and how many of them were not, per category.
A metric with nothing to report says so with a None or an infinity - a time
to solution of a run that never reached the optimum is the usual one, since the
expected time to something that did not happen is unbounded. Neither is a height
a bar can have, and leaving them in poisons the aggregate: one infinity turns the
mean of an algorithm into an infinity, and a missing value silently shortens it.
What happens to them is :attr:missing, and by default it is nothing: the plot
raises rather than quietly showing a mean over fewer models than it claims. Asked
to carry on, it either leaves them out or fills them from the values that could be
drawn - Missing(policy="max") puts them just past the tallest bar, which is
where "worse than everything here" belongs. Either way they are counted and a
warning is logged: a bar resting on half its models is a different statement from
one resting on all of them, and that is not visible in the bar itself.
Parameters:
-
df(DataFrame) –The plotting data.
-
column(str) –Column holding the plotted value.
-
by(str | None, default:None) –Column whose categories the missing values are counted per, e.g. the x-axis of a bar plot. Without one they are counted under
"". -
within(str | None, default:None) –Column that splits those categories further, e.g. the grouping of a bar plot. Counting per group is what lets a figure mark the one bar of a group that lost values rather than the whole category it sits in.
Returns:
-
tuple[DataFrame, dict[tuple[str, str], int]]–The rows to draw, and the number of missing values per category and group - the group is
""where there is none. The mapping is empty when nothing was missing.
Raises:
-
PlotMissingValuesError–If values are missing and the policy is
"raise".
place_legend(axes: Axes, handles: list[Any] | None = None, labels: list[str] | None = None) -> None
Put the legend beside the axes, whatever drew it.
Outside the axes for a figure of its own: a legend inside sits on top of the data, and which corner is free depends on the run rather than on the plot - the figure would move its own key around as the numbers change. Beside it, the key is always in the same place and covers nothing.
A panel of someone else's figure is the exception. The room beside it belongs to the panel next to it, so a key anchored there is drawn over a neighbour rather than over the data; inside the panel it stays within the space the plot was given.
Parameters:
note_missing(handles: list[Any], labels: list[str], missing: dict[tuple[str, str], int]) -> None
Add the legend entry that says how many values the figure could not draw.
What a plot can say beyond that depends on what it draws. A bar has a slot of its
own to put a cross under, so BarPlot marks the categories themselves; a point in
a cloud or a step of a sweep has no slot, and the count in the key is the whole
statement there - enough that a filled value is not read as a measured one.
Parameters:
apply_theme() -> None
Install the seaborn theme this plot is drawn under, unless it has none.
The theme is matplotlib's global state rather than a property of one figure, so
it is installed before the figure is built and left in place afterwards: a
benchmark themes its plots by handing every one of them the same Theme, not by
each plot putting the previous look back.
apply_grid(axes: Axes) -> None
Draw the gridlines the theme asks for, behind everything else on axes.
Parameters:
-
axes(Axes) –The axes the plot was drawn on.
setup_figure() -> None
Create a matplotlib figure, unless the plot is drawing into a shared axes.
save_figure(save_dir: str) -> list[Path]
finalize_plot(xlabel: str, ylabel: str, title: str, ylim: tuple[float, float] | None = None, x_rotation: int = 45, save_dir: str | None = None) -> None
Apply common axis labels, title, limits, and display behavior.
Parameters:
-
xlabel(str) –Label for the x-axis.
-
ylabel(str) –Label for the y-axis.
-
title(str) –Plot title.
-
ylim(tuple[float, float] | None, default:None) –Lower and upper y-axis limits, by default
None. -
x_rotation(int, default:45) –Rotation angle for x-axis tick labels, by default
45. -
save_dir(str | None, default:None) –Directory to save the figure into, by default
None.
ScatterPlot
Bases: SeabornPlot, ABC
Base helper for generating seaborn scatter plots.
Requires
Install the 'pre-defined' extra: pip install luna-bench[pre-defined]
figure: Figure = Figure()
class-attribute
instance-attribute
The figure this plot is drawn on and the files written from it.
theme: Theme | None = Theme()
class-attribute
instance-attribute
The seaborn theme the figure is drawn under, and the gridlines behind the marks.
A figure is read against its axis, so it is drawn with the lines that make that
possible unless asked otherwise. None takes the theme and the grid away.
missing: Missing = Missing()
class-attribute
instance-attribute
What becomes of the values the plot cannot draw, and how it says they were there.
option_bundles: dict[str, type[OptionBundle]] = {'style': PlotStyle}
class-attribute
Constructor arguments that configure several fields at once, and the bundle each takes.
A style is spread over the bundle fields rather than stored, so a benchmark can
hand the same look to every plot while each keeps what it says itself. Applied least
specific first: the shared style, then a bundle passed to the plot, then a flat
option.
create(*, rows: list[dict[str, Any]], xlabel: str, ylabel: str, title: str, hue: str, x: str = 'x', y: str = 'y', hline: float | None = None, hline_label: str | None = None, hcolor: str = REFERENCE_LINE_COLOUR, save_dir: str | None = None, **kwargs: Any) -> None
Create a scatter plot from row-oriented data.
Parameters:
-
rows(dict[str, Any]) –Row-oriented mapping used to construct the plotting DataFrame.
-
xlabel(str) –Label for the x-axis.
-
ylabel(str) –Label for the y-axis.
-
title(str) –Plot title.
-
hue(str) –Column used to color points by group.
-
x(str, default:'x') –Column name mapped to the x-axis, by default
"x". -
y(str, default:'y') –Column name mapped to the y-axis, by default
"y". -
hline(float | None, default:None) –Optional horizontal reference line value, by default
None. -
hline_label(str | None, default:None) –Legend label for the horizontal reference line, by default
None. -
hcolor(str, default:REFERENCE_LINE_COLOUR) –Color of the horizontal reference line, by default black.
-
save_dir(str | None, default:None) –Directory to save the figure into, by default
None. -
**kwargs(Any, default:{}) –Additional keyword arguments forwarded to :func:
seaborn.scatterplot. They override the defaults computed here, so anything seaborn understands (palette,style,size,markers, ...) can be tuned from the call site.
run(benchmark_results: BenchmarkResultContainer, save_dir: str | None = None) -> None
abstractmethod
Generate plot output from benchmark results.
Parameters:
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data consumed by the plot implementation.
draw_into(axes: Axes, benchmark_results: BenchmarkResultContainer) -> None
Run this plot onto an existing axes rather than into a figure of its own.
Everything the plot draws goes through the pyplot state, so making that axes the current one is enough to redirect it. The figure, the files, and the window stay the caller's business - which is what lets several plots share one figure, e.g. the summary grid.
Parameters:
-
axes(Axes) –The axes to draw on.
-
benchmark_results(BenchmarkResultContainer) –Aggregated benchmark data handed to :meth:
run.
resolve_missing(df: pd.DataFrame, column: str, *, by: str | None = None, within: str | None = None) -> tuple[pd.DataFrame, dict[tuple[str, str], int]]
Return the drawable rows and how many of them were not, per category.
A metric with nothing to report says so with a None or an infinity - a time
to solution of a run that never reached the optimum is the usual one, since the
expected time to something that did not happen is unbounded. Neither is a height
a bar can have, and leaving them in poisons the aggregate: one infinity turns the
mean of an algorithm into an infinity, and a missing value silently shortens it.
What happens to them is :attr:missing, and by default it is nothing: the plot
raises rather than quietly showing a mean over fewer models than it claims. Asked
to carry on, it either leaves them out or fills them from the values that could be
drawn - Missing(policy="max") puts them just past the tallest bar, which is
where "worse than everything here" belongs. Either way they are counted and a
warning is logged: a bar resting on half its models is a different statement from
one resting on all of them, and that is not visible in the bar itself.
Parameters:
-
df(DataFrame) –The plotting data.
-
column(str) –Column holding the plotted value.
-
by(str | None, default:None) –Column whose categories the missing values are counted per, e.g. the x-axis of a bar plot. Without one they are counted under
"". -
within(str | None, default:None) –Column that splits those categories further, e.g. the grouping of a bar plot. Counting per group is what lets a figure mark the one bar of a group that lost values rather than the whole category it sits in.
Returns:
-
tuple[DataFrame, dict[tuple[str, str], int]]–The rows to draw, and the number of missing values per category and group - the group is
""where there is none. The mapping is empty when nothing was missing.
Raises:
-
PlotMissingValuesError–If values are missing and the policy is
"raise".
place_legend(axes: Axes, handles: list[Any] | None = None, labels: list[str] | None = None) -> None
Put the legend beside the axes, whatever drew it.
Outside the axes for a figure of its own: a legend inside sits on top of the data, and which corner is free depends on the run rather than on the plot - the figure would move its own key around as the numbers change. Beside it, the key is always in the same place and covers nothing.
A panel of someone else's figure is the exception. The room beside it belongs to the panel next to it, so a key anchored there is drawn over a neighbour rather than over the data; inside the panel it stays within the space the plot was given.
Parameters:
note_missing(handles: list[Any], labels: list[str], missing: dict[tuple[str, str], int]) -> None
Add the legend entry that says how many values the figure could not draw.
What a plot can say beyond that depends on what it draws. A bar has a slot of its
own to put a cross under, so BarPlot marks the categories themselves; a point in
a cloud or a step of a sweep has no slot, and the count in the key is the whole
statement there - enough that a filled value is not read as a measured one.
Parameters:
apply_theme() -> None
Install the seaborn theme this plot is drawn under, unless it has none.
The theme is matplotlib's global state rather than a property of one figure, so
it is installed before the figure is built and left in place afterwards: a
benchmark themes its plots by handing every one of them the same Theme, not by
each plot putting the previous look back.
apply_grid(axes: Axes) -> None
Draw the gridlines the theme asks for, behind everything else on axes.
Parameters:
-
axes(Axes) –The axes the plot was drawn on.
setup_figure() -> None
Create a matplotlib figure, unless the plot is drawing into a shared axes.
save_figure(save_dir: str) -> list[Path]
finalize_plot(xlabel: str, ylabel: str, title: str, ylim: tuple[float, float] | None = None, x_rotation: int = 45, save_dir: str | None = None) -> None
Apply common axis labels, title, limits, and display behavior.
Parameters:
-
xlabel(str) –Label for the x-axis.
-
ylabel(str) –Label for the y-axis.
-
title(str) –Plot title.
-
ylim(tuple[float, float] | None, default:None) –Lower and upper y-axis limits, by default
None. -
x_rotation(int, default:45) –Rotation angle for x-axis tick labels, by default
45. -
save_dir(str | None, default:None) –Directory to save the figure into, by default
None.