Coverage for src/jquantstats/_plots/_data/_distribution.py: 100%
11 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 04:11 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 04:11 +0000
1"""Return-distribution charts (overlaid histograms and by-period box plots)."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, Literal, overload
7from .._render import render
8from .._specs import distribution_spec, histogram_spec
10if TYPE_CHECKING:
11 from matplotlib.figure import Figure as MplFigure
12 from plotly.graph_objects import Figure as PlotlyFigure
14 from jquantstats._protocol import DataLike
16 from .._backend import Backend
17 from .._render import Figure
20class _DistributionPlotsMixin:
21 """Return-distribution plots for :class:`DataPlots`."""
23 __slots__ = ()
25 _data: DataLike
27 @overload
28 def histogram(
29 self, title: str = ..., bins: int = ..., *, backend: Literal["plotly"] | None = ...
30 ) -> PlotlyFigure: ...
32 @overload
33 def histogram(self, title: str = ..., bins: int = ..., *, backend: Literal["matplotlib"]) -> MplFigure: ...
35 def histogram(
36 self,
37 title: str = "Returns Distribution",
38 bins: int = 50,
39 *,
40 backend: Backend | None = None,
41 ) -> Figure:
42 """Overlaid return histograms, one per series.
44 Each asset (and the benchmark, when present) is drawn as a
45 semi-transparent histogram on shared axes, so the distributions can be
46 compared directly — a fat-tailed asset against a tightly peaked
47 benchmark, for instance.
49 Args:
50 title: Chart title. Defaults to ``"Returns Distribution"``.
51 bins: Number of histogram bins. Defaults to 50.
52 backend: Renderer to use. Defaults to the ambient selection.
54 Returns:
55 Figure: A histogram figure.
57 """
58 return render(histogram_spec(self._data, title=title, bins=bins), backend)
60 @overload
61 def distribution(
62 self, title: str = ..., compounded: bool = ..., *, backend: Literal["plotly"] | None = ...
63 ) -> PlotlyFigure: ...
65 @overload
66 def distribution(
67 self, title: str = ..., compounded: bool = ..., *, backend: Literal["matplotlib"]
68 ) -> MplFigure: ...
70 def distribution(
71 self,
72 title: str = "Return Distribution by Period",
73 compounded: bool = True,
74 *,
75 backend: Backend | None = None,
76 ) -> Figure:
77 """Return distributions across daily, weekly, monthly, quarterly and yearly periods.
79 Renders a box plot for each aggregation period so the user can compare
80 how the distribution widens as the holding period lengthens. One
81 subplot column is produced per asset.
83 Args:
84 title: Chart title. Defaults to ``"Return Distribution by Period"``.
85 compounded: Compound returns within each period. Defaults to True.
86 backend: Renderer to use. Defaults to the ambient selection.
88 Returns:
89 Figure: A figure with one panel per asset.
91 """
92 return render(distribution_spec(self._data, title=title, compounded=compounded), backend)