plotnine 0.15.3__py3-none-any.whl → 0.16.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plotnine/_mpl/gridspec.py +50 -6
- plotnine/_mpl/layout_manager/__init__.py +2 -5
- plotnine/_mpl/layout_manager/_composition_layout_items.py +98 -0
- plotnine/_mpl/layout_manager/_composition_side_space.py +461 -0
- plotnine/_mpl/layout_manager/_engine.py +19 -58
- plotnine/_mpl/layout_manager/_grid.py +94 -0
- plotnine/_mpl/layout_manager/_layout_tree.py +402 -817
- plotnine/_mpl/layout_manager/{_layout_items.py → _plot_layout_items.py} +55 -278
- plotnine/_mpl/layout_manager/{_spaces.py → _plot_side_space.py} +111 -291
- plotnine/_mpl/layout_manager/_side_space.py +176 -0
- plotnine/_mpl/utils.py +259 -1
- plotnine/_utils/__init__.py +23 -3
- plotnine/_utils/context.py +9 -13
- plotnine/_utils/dataclasses.py +24 -0
- plotnine/animation.py +13 -12
- plotnine/composition/__init__.py +6 -0
- plotnine/composition/_beside.py +13 -11
- plotnine/composition/_compose.py +263 -99
- plotnine/composition/_plot_annotation.py +75 -0
- plotnine/composition/_plot_layout.py +143 -0
- plotnine/composition/_plot_spacer.py +1 -1
- plotnine/composition/_stack.py +13 -11
- plotnine/composition/_types.py +28 -0
- plotnine/composition/_wrap.py +60 -0
- plotnine/facets/facet.py +9 -12
- plotnine/facets/facet_grid.py +2 -2
- plotnine/facets/facet_wrap.py +1 -1
- plotnine/geoms/geom.py +2 -2
- plotnine/geoms/geom_map.py +4 -5
- plotnine/geoms/geom_path.py +8 -7
- plotnine/geoms/geom_rug.py +6 -10
- plotnine/geoms/geom_text.py +5 -5
- plotnine/ggplot.py +63 -9
- plotnine/guides/guide.py +24 -6
- plotnine/guides/guide_colorbar.py +88 -46
- plotnine/guides/guide_legend.py +47 -20
- plotnine/guides/guides.py +2 -2
- plotnine/iapi.py +17 -1
- plotnine/scales/scale.py +1 -1
- plotnine/stats/binning.py +15 -43
- plotnine/stats/smoothers.py +7 -3
- plotnine/stats/stat.py +2 -2
- plotnine/stats/stat_density_2d.py +10 -6
- plotnine/stats/stat_pointdensity.py +8 -1
- plotnine/stats/stat_qq.py +5 -5
- plotnine/stats/stat_qq_line.py +6 -1
- plotnine/stats/stat_sina.py +19 -20
- plotnine/stats/stat_summary.py +4 -2
- plotnine/stats/stat_summary_bin.py +7 -1
- plotnine/themes/elements/element_line.py +2 -0
- plotnine/themes/elements/element_text.py +12 -1
- plotnine/themes/theme.py +18 -24
- plotnine/themes/themeable.py +17 -3
- plotnine/typing.py +6 -1
- {plotnine-0.15.3.dist-info → plotnine-0.16.0a1.dist-info}/METADATA +3 -3
- {plotnine-0.15.3.dist-info → plotnine-0.16.0a1.dist-info}/RECORD +59 -51
- {plotnine-0.15.3.dist-info → plotnine-0.16.0a1.dist-info}/WHEEL +1 -1
- plotnine/composition/_plotspec.py +0 -50
- {plotnine-0.15.3.dist-info → plotnine-0.16.0a1.dist-info}/licenses/LICENSE +0 -0
- {plotnine-0.15.3.dist-info → plotnine-0.16.0a1.dist-info}/top_level.txt +0 -0
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
|
-
from warnings import warn
|
|
5
4
|
|
|
6
5
|
from matplotlib.layout_engine import LayoutEngine
|
|
7
6
|
|
|
8
|
-
from
|
|
9
|
-
from .
|
|
10
|
-
from ._spaces import LayoutSpaces
|
|
7
|
+
from ._composition_side_space import CompositionSideSpaces
|
|
8
|
+
from ._plot_side_space import PlotSideSpaces
|
|
11
9
|
|
|
12
10
|
if TYPE_CHECKING:
|
|
13
11
|
from matplotlib.figure import Figure
|
|
@@ -18,70 +16,33 @@ if TYPE_CHECKING:
|
|
|
18
16
|
|
|
19
17
|
class PlotnineLayoutEngine(LayoutEngine):
|
|
20
18
|
"""
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
the
|
|
19
|
+
Geometry management for plotnine plots
|
|
20
|
+
|
|
21
|
+
It works for both singular plots (ggplot) and compositions (Compose).
|
|
22
|
+
For plots, it adjusts the position of objects around the panels and/or
|
|
23
|
+
resizes the plot to the desired aspect-ratio. For compositions, it
|
|
24
|
+
adjusts the position of objects (the annotations of the top-level
|
|
25
|
+
composition) around the plots, and also the artists around the panels
|
|
26
|
+
in all the contained plots.
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
_adjust_compatible = True
|
|
30
30
|
_colorbar_gridspec = False
|
|
31
31
|
|
|
32
|
-
def __init__(self,
|
|
33
|
-
self.
|
|
34
|
-
self.theme = plot.theme
|
|
32
|
+
def __init__(self, item: ggplot | Compose):
|
|
33
|
+
self.item = item
|
|
35
34
|
|
|
36
35
|
def execute(self, fig: Figure):
|
|
37
36
|
from contextlib import nullcontext
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
with getattr(renderer, "_draw_disabled", nullcontext)():
|
|
42
|
-
spaces = LayoutSpaces(self.plot)
|
|
43
|
-
|
|
44
|
-
gsparams = spaces.get_gridspec_params()
|
|
45
|
-
self.plot.facet._panels_gridspec.layout(gsparams)
|
|
46
|
-
spaces.items._adjust_positions(spaces)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class PlotnineCompositionLayoutEngine(LayoutEngine):
|
|
50
|
-
"""
|
|
51
|
-
Layout Manager for Plotnine Composition
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
_adjust_compatible = True
|
|
55
|
-
_colorbar_gridspec = False
|
|
56
|
-
|
|
57
|
-
def __init__(self, composition: Compose):
|
|
58
|
-
self.composition = composition
|
|
59
|
-
|
|
60
|
-
def execute(self, fig: Figure):
|
|
61
|
-
from contextlib import nullcontext
|
|
38
|
+
from plotnine import ggplot
|
|
62
39
|
|
|
40
|
+
item = self.item
|
|
63
41
|
renderer = fig._get_renderer() # pyright: ignore[reportAttributeAccessIssue]
|
|
64
42
|
|
|
65
|
-
# Caculate the space taken up by all plot artists
|
|
66
|
-
lookup_spaces: dict[ggplot, LayoutSpaces] = {}
|
|
67
43
|
with getattr(renderer, "_draw_disabled", nullcontext)():
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
tree.harmonise()
|
|
74
|
-
|
|
75
|
-
# Set the final positions of the artists in each plot
|
|
76
|
-
for plot, spaces in lookup_spaces.items():
|
|
77
|
-
gsparams = spaces.get_gridspec_params()
|
|
78
|
-
if not gsparams.valid:
|
|
79
|
-
warn(
|
|
80
|
-
"The layout manager failed, the figure size is too small "
|
|
81
|
-
"to contain all the plots. Use theme() increase the "
|
|
82
|
-
"figure size and/or reduce the size of the texts.",
|
|
83
|
-
PlotnineWarning,
|
|
84
|
-
)
|
|
85
|
-
break
|
|
86
|
-
plot.facet._panels_gridspec.layout(gsparams)
|
|
87
|
-
spaces.items._adjust_positions(spaces)
|
|
44
|
+
if isinstance(item, ggplot):
|
|
45
|
+
item._sidespaces = PlotSideSpaces(item)
|
|
46
|
+
else:
|
|
47
|
+
item._sidespaces = CompositionSideSpaces(item)
|
|
48
|
+
item._sidespaces.arrange()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
2
|
+
from dataclasses import InitVar, dataclass
|
|
3
|
+
from typing import (
|
|
4
|
+
Generic,
|
|
5
|
+
Literal,
|
|
6
|
+
Sequence,
|
|
7
|
+
TypeVar,
|
|
8
|
+
overload,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
T = TypeVar("T")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class Grid(Generic[T]):
|
|
18
|
+
nrow: InitVar[int]
|
|
19
|
+
ncol: InitVar[int]
|
|
20
|
+
items: InitVar[Sequence[T]]
|
|
21
|
+
order: InitVar[Literal["row_major", "col_major"]] = "row_major"
|
|
22
|
+
"""
|
|
23
|
+
Put items into the grid left->right, top->bottom starting at `start`.
|
|
24
|
+
Unfilled cells remain None. Returns the number of items written.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __post_init__(
|
|
28
|
+
self,
|
|
29
|
+
nrow: int,
|
|
30
|
+
ncol: int,
|
|
31
|
+
items: Sequence[T],
|
|
32
|
+
order: Literal["row_major", "col_major"],
|
|
33
|
+
):
|
|
34
|
+
self._grid = np.empty((nrow, ncol), dtype=object)
|
|
35
|
+
|
|
36
|
+
r, c = 0, 0
|
|
37
|
+
if order == "row_major":
|
|
38
|
+
for item in items:
|
|
39
|
+
self[r, c] = item
|
|
40
|
+
c += 1
|
|
41
|
+
if c >= ncol:
|
|
42
|
+
r, c = r + 1, 0
|
|
43
|
+
else:
|
|
44
|
+
for item in items:
|
|
45
|
+
self[r, c] = item
|
|
46
|
+
r += 1
|
|
47
|
+
if r >= nrow:
|
|
48
|
+
r, c = 0, c + 1
|
|
49
|
+
|
|
50
|
+
@overload
|
|
51
|
+
def __getitem__(self, index: tuple[int, int]) -> T | None: ...
|
|
52
|
+
|
|
53
|
+
@overload
|
|
54
|
+
def __getitem__(self, index: tuple[int, slice]) -> list[T | None]: ...
|
|
55
|
+
|
|
56
|
+
@overload
|
|
57
|
+
def __getitem__(self, index: tuple[slice, int]) -> list[T | None]: ...
|
|
58
|
+
|
|
59
|
+
@overload
|
|
60
|
+
def __getitem__(
|
|
61
|
+
self,
|
|
62
|
+
index: tuple[slice, slice],
|
|
63
|
+
) -> list[list[T | None]]: ...
|
|
64
|
+
|
|
65
|
+
def __getitem__(
|
|
66
|
+
self, index: tuple[int | slice, int | slice]
|
|
67
|
+
) -> T | None | list[T | None] | list[list[T | None]]:
|
|
68
|
+
"""
|
|
69
|
+
Access grid items with 2D indexing:
|
|
70
|
+
"""
|
|
71
|
+
return self._grid[index] # pyright: ignore[reportReturnType]
|
|
72
|
+
|
|
73
|
+
def __setitem__(
|
|
74
|
+
self,
|
|
75
|
+
index: tuple[int | slice, slice | int],
|
|
76
|
+
value: T | None | list[T | None] | list[list[T | None]],
|
|
77
|
+
) -> None:
|
|
78
|
+
self._grid[index] = value
|
|
79
|
+
|
|
80
|
+
def iter_rows(self) -> Iterator[list[T | None]]:
|
|
81
|
+
"""
|
|
82
|
+
Row by row
|
|
83
|
+
"""
|
|
84
|
+
n = self._grid.shape[0]
|
|
85
|
+
for row in range(n):
|
|
86
|
+
yield self[row, :]
|
|
87
|
+
|
|
88
|
+
def iter_cols(self) -> Iterator[list[T | None]]:
|
|
89
|
+
"""
|
|
90
|
+
Column by column
|
|
91
|
+
"""
|
|
92
|
+
n = self._grid.shape[1]
|
|
93
|
+
for col in range(n):
|
|
94
|
+
yield self[:, col]
|