plotnine 0.15.0a3__py3-none-any.whl → 0.15.0a4__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/_utils/__init__.py +5 -103
- plotnine/doctools.py +3 -3
- plotnine/geoms/annotate.py +10 -10
- plotnine/geoms/geom.py +25 -16
- plotnine/layer.py +2 -0
- plotnine/mapping/aes.py +75 -45
- plotnine/scales/scale_continuous.py +1 -1
- plotnine/scales/scale_discrete.py +1 -1
- plotnine/stats/stat_density_2d.py +1 -1
- {plotnine-0.15.0a3.dist-info → plotnine-0.15.0a4.dist-info}/METADATA +2 -2
- {plotnine-0.15.0a3.dist-info → plotnine-0.15.0a4.dist-info}/RECORD +14 -14
- {plotnine-0.15.0a3.dist-info → plotnine-0.15.0a4.dist-info}/WHEEL +0 -0
- {plotnine-0.15.0a3.dist-info → plotnine-0.15.0a4.dist-info}/licenses/LICENSE +0 -0
- {plotnine-0.15.0a3.dist-info → plotnine-0.15.0a4.dist-info}/top_level.txt +0 -0
plotnine/_utils/__init__.py
CHANGED
|
@@ -12,9 +12,10 @@ from collections.abc import Iterable, Sequence
|
|
|
12
12
|
from contextlib import suppress
|
|
13
13
|
from copy import deepcopy
|
|
14
14
|
from dataclasses import field
|
|
15
|
-
from typing import TYPE_CHECKING
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
16
|
from warnings import warn
|
|
17
17
|
|
|
18
|
+
import mizani._colors.utils as color_utils
|
|
18
19
|
import numpy as np
|
|
19
20
|
import pandas as pd
|
|
20
21
|
from pandas.core.groupby import DataFrameGroupBy
|
|
@@ -26,12 +27,10 @@ if TYPE_CHECKING:
|
|
|
26
27
|
from typing import Any, Callable, Literal, TypeVar
|
|
27
28
|
|
|
28
29
|
import numpy.typing as npt
|
|
29
|
-
from matplotlib.typing import ColorType
|
|
30
30
|
from typing_extensions import TypeGuard
|
|
31
31
|
|
|
32
32
|
from plotnine.typing import (
|
|
33
33
|
AnyArrayLike,
|
|
34
|
-
AnySeries,
|
|
35
34
|
DataLike,
|
|
36
35
|
FloatArray,
|
|
37
36
|
FloatArrayLike,
|
|
@@ -60,6 +59,8 @@ BOX_LOCATIONS: dict[str, tuple[float, float]] = {
|
|
|
60
59
|
"centre": (0.5, 0.5),
|
|
61
60
|
}
|
|
62
61
|
|
|
62
|
+
to_rgba = color_utils.to_rgba
|
|
63
|
+
|
|
63
64
|
|
|
64
65
|
def is_scalar(val):
|
|
65
66
|
"""
|
|
@@ -361,7 +362,7 @@ def _id_var(x: AnyArrayLike, drop: bool = False) -> list[int]:
|
|
|
361
362
|
lst = match(x, levels)
|
|
362
363
|
lst = [item + 1 for item in lst]
|
|
363
364
|
|
|
364
|
-
return lst
|
|
365
|
+
return lst
|
|
365
366
|
|
|
366
367
|
|
|
367
368
|
def join_keys(x, y, by=None):
|
|
@@ -530,105 +531,6 @@ def remove_missing(
|
|
|
530
531
|
return data
|
|
531
532
|
|
|
532
533
|
|
|
533
|
-
@overload
|
|
534
|
-
def to_rgba(colors: ColorType, alpha: float) -> ColorType: ...
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
@overload
|
|
538
|
-
def to_rgba(
|
|
539
|
-
colors: Sequence[ColorType], alpha: float
|
|
540
|
-
) -> Sequence[ColorType] | ColorType: ...
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
@overload
|
|
544
|
-
def to_rgba(
|
|
545
|
-
colors: AnySeries, alpha: AnySeries
|
|
546
|
-
) -> Sequence[ColorType] | ColorType: ...
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
def to_rgba(
|
|
550
|
-
colors: Sequence[ColorType] | AnySeries | ColorType,
|
|
551
|
-
alpha: float | Sequence[float] | AnySeries,
|
|
552
|
-
) -> Sequence[ColorType] | ColorType:
|
|
553
|
-
"""
|
|
554
|
-
Convert hex colors to rgba values.
|
|
555
|
-
|
|
556
|
-
Parameters
|
|
557
|
-
----------
|
|
558
|
-
colors : iterable | str
|
|
559
|
-
colors to convert
|
|
560
|
-
alphas : iterable | float
|
|
561
|
-
alpha values
|
|
562
|
-
|
|
563
|
-
Returns
|
|
564
|
-
-------
|
|
565
|
-
out : ndarray | tuple
|
|
566
|
-
rgba color(s)
|
|
567
|
-
|
|
568
|
-
Notes
|
|
569
|
-
-----
|
|
570
|
-
Matplotlib plotting functions only accept scalar
|
|
571
|
-
alpha values. Hence no two objects with different
|
|
572
|
-
alpha values may be plotted in one call. This would
|
|
573
|
-
make plots with continuous alpha values innefficient.
|
|
574
|
-
However :), the colors can be rgba hex values or
|
|
575
|
-
list-likes and the alpha dimension will be respected.
|
|
576
|
-
"""
|
|
577
|
-
|
|
578
|
-
def is_iterable(var):
|
|
579
|
-
return np.iterable(var) and not isinstance(var, str)
|
|
580
|
-
|
|
581
|
-
def has_alpha(c):
|
|
582
|
-
return (isinstance(c, tuple) and len(c) == 4) or (
|
|
583
|
-
isinstance(c, str) and len(c) == 9 and c[0] == "#"
|
|
584
|
-
)
|
|
585
|
-
|
|
586
|
-
def no_color(c):
|
|
587
|
-
return c is None or c.lower() in ("none", "")
|
|
588
|
-
|
|
589
|
-
def to_rgba_hex(c: ColorType, a: float) -> str:
|
|
590
|
-
"""
|
|
591
|
-
Convert rgb color to rgba hex value
|
|
592
|
-
|
|
593
|
-
If color c has an alpha channel, then alpha value
|
|
594
|
-
a is ignored
|
|
595
|
-
"""
|
|
596
|
-
from matplotlib.colors import colorConverter, to_hex
|
|
597
|
-
|
|
598
|
-
if c in ("None", "none"):
|
|
599
|
-
return c
|
|
600
|
-
|
|
601
|
-
_has_alpha = has_alpha(c)
|
|
602
|
-
c = to_hex(c, keep_alpha=_has_alpha)
|
|
603
|
-
|
|
604
|
-
if not _has_alpha:
|
|
605
|
-
arr = colorConverter.to_rgba(c, a)
|
|
606
|
-
return to_hex(arr, keep_alpha=True)
|
|
607
|
-
|
|
608
|
-
return c
|
|
609
|
-
|
|
610
|
-
if is_iterable(colors):
|
|
611
|
-
colors = cast("Sequence[ColorType]", colors)
|
|
612
|
-
|
|
613
|
-
if all(no_color(c) for c in colors):
|
|
614
|
-
return "none"
|
|
615
|
-
|
|
616
|
-
if isinstance(alpha, (Sequence, pd.Series)):
|
|
617
|
-
return [to_rgba_hex(c, a) for c, a in zip(colors, alpha)]
|
|
618
|
-
else:
|
|
619
|
-
return [to_rgba_hex(c, alpha) for c in colors]
|
|
620
|
-
else:
|
|
621
|
-
colors = cast("ColorType", colors)
|
|
622
|
-
|
|
623
|
-
if no_color(colors):
|
|
624
|
-
return colors
|
|
625
|
-
|
|
626
|
-
if isinstance(alpha, (Sequence, pd.Series)):
|
|
627
|
-
return [to_rgba_hex(colors, a) for a in alpha]
|
|
628
|
-
else:
|
|
629
|
-
return to_rgba_hex(colors, alpha)
|
|
630
|
-
|
|
631
|
-
|
|
632
534
|
def groupby_apply(
|
|
633
535
|
df: pd.DataFrame,
|
|
634
536
|
cols: str | list[str],
|
plotnine/doctools.py
CHANGED
|
@@ -71,7 +71,7 @@ STAT_SIGNATURE_TPL = """
|
|
|
71
71
|
|
|
72
72
|
common_params_doc = {
|
|
73
73
|
"mapping": """\
|
|
74
|
-
Aesthetic mappings created with [aes](:class:`plotnine.mapping.aes`). If \
|
|
74
|
+
Aesthetic mappings created with [aes](:class:`plotnine.mapping.aes.aes`). If \
|
|
75
75
|
specified and `inherit_aes=True`{.py}, it is combined with the default \
|
|
76
76
|
mapping for the plot. You must supply mapping if there is no plot mapping.""",
|
|
77
77
|
"data": """\
|
|
@@ -103,7 +103,7 @@ the final image is in vector format.""",
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
GEOM_PARAMS_TPL = """
|
|
106
|
-
mapping : ~plotnine.mapping.aes, default=None
|
|
106
|
+
mapping : ~plotnine.mapping.aes.aes, default=None
|
|
107
107
|
{mapping}
|
|
108
108
|
{_aesthetics_doc}
|
|
109
109
|
data : ~pandas.DataFrame, default=None
|
|
@@ -124,7 +124,7 @@ raster : bool, default={default_raster}
|
|
|
124
124
|
"""
|
|
125
125
|
|
|
126
126
|
STAT_PARAMS_TPL = """
|
|
127
|
-
mapping : ~plotnine.mapping.aes, default=None
|
|
127
|
+
mapping : ~plotnine.mapping.aes.aes, default=None
|
|
128
128
|
{mapping}
|
|
129
129
|
{_aesthetics_doc}
|
|
130
130
|
data : ~pandas.DataFrame, default=None
|
plotnine/geoms/annotate.py
CHANGED
|
@@ -64,16 +64,16 @@ class annotate:
|
|
|
64
64
|
def __init__(
|
|
65
65
|
self,
|
|
66
66
|
geom: str | type[geom_base_class],
|
|
67
|
-
x: float | None = None,
|
|
68
|
-
y: float | None = None,
|
|
69
|
-
xmin: float | None = None,
|
|
70
|
-
xmax: float | None = None,
|
|
71
|
-
xend: float | None = None,
|
|
72
|
-
xintercept: float | None = None,
|
|
73
|
-
ymin: float | None = None,
|
|
74
|
-
ymax: float | None = None,
|
|
75
|
-
yend: float | None = None,
|
|
76
|
-
yintercept: float | None = None,
|
|
67
|
+
x: float | list[float] | None = None,
|
|
68
|
+
y: float | list[float] | None = None,
|
|
69
|
+
xmin: float | list[float] | None = None,
|
|
70
|
+
xmax: float | list[float] | None = None,
|
|
71
|
+
xend: float | list[float] | None = None,
|
|
72
|
+
xintercept: float | list[float] | None = None,
|
|
73
|
+
ymin: float | list[float] | None = None,
|
|
74
|
+
ymax: float | list[float] | None = None,
|
|
75
|
+
yend: float | list[float] | None = None,
|
|
76
|
+
yintercept: float | list[float] | None = None,
|
|
77
77
|
**kwargs: Any,
|
|
78
78
|
):
|
|
79
79
|
variables = locals()
|
plotnine/geoms/geom.py
CHANGED
|
@@ -7,13 +7,12 @@ from itertools import chain, repeat
|
|
|
7
7
|
|
|
8
8
|
from .._utils import (
|
|
9
9
|
data_mapping_as_kwargs,
|
|
10
|
-
is_list_like,
|
|
11
10
|
remove_missing,
|
|
12
11
|
)
|
|
13
12
|
from .._utils.registry import Register, Registry
|
|
14
13
|
from ..exceptions import PlotnineError
|
|
15
14
|
from ..layer import layer
|
|
16
|
-
from ..mapping.aes import
|
|
15
|
+
from ..mapping.aes import RepeatAesthetic, rename_aesthetics
|
|
17
16
|
from ..mapping.evaluation import evaluate
|
|
18
17
|
from ..positions.position import position
|
|
19
18
|
from ..stats.stat import stat
|
|
@@ -179,11 +178,16 @@ class geom(ABC, metaclass=Register):
|
|
|
179
178
|
----------
|
|
180
179
|
data :
|
|
181
180
|
Data
|
|
181
|
+
"""
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
def setup_aes_params(self, data: pd.DataFrame):
|
|
184
|
+
"""
|
|
185
|
+
Override this method to verify and/or adjust aesthetic parameters
|
|
186
|
+
|
|
187
|
+
Parameters
|
|
188
|
+
----------
|
|
189
|
+
data :
|
|
190
|
+
Data
|
|
187
191
|
"""
|
|
188
192
|
|
|
189
193
|
def setup_data(self, data: pd.DataFrame) -> pd.DataFrame:
|
|
@@ -255,23 +259,28 @@ class geom(ABC, metaclass=Register):
|
|
|
255
259
|
data[ae] = evaled[ae]
|
|
256
260
|
|
|
257
261
|
num_panels = len(data["PANEL"].unique()) if "PANEL" in data else 1
|
|
262
|
+
across_panels = num_panels > 1 and not self.params["inherit_aes"]
|
|
258
263
|
|
|
259
264
|
# Aesthetics set as parameters to the geom/stat
|
|
260
265
|
for ae, value in self.aes_params.items():
|
|
261
266
|
try:
|
|
262
267
|
data[ae] = value
|
|
263
268
|
except ValueError as e:
|
|
264
|
-
#
|
|
265
|
-
#
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
# NOTE: Handling of the edgecases in this exception is not
|
|
270
|
+
# foolproof.
|
|
271
|
+
repeat_ae = getattr(RepeatAesthetic, ae, None)
|
|
272
|
+
if across_panels:
|
|
273
|
+
# Adding an annotation/abline/hline/vhline with multiple
|
|
274
|
+
# items across to more than 1 panel
|
|
275
|
+
value = list(chain(*repeat(value, num_panels)))
|
|
276
|
+
data[ae] = value
|
|
277
|
+
elif repeat_ae:
|
|
278
|
+
# Some aesthetics may have valid values that are not
|
|
279
|
+
# scalar. e.g. sequences. For such case, we need to
|
|
280
|
+
# insert a sequence of the same value.
|
|
281
|
+
data[ae] = repeat_ae(value, len(data))
|
|
270
282
|
else:
|
|
271
|
-
msg =
|
|
272
|
-
f"'{value}' does not look like a "
|
|
273
|
-
f"valid value for `{ae}`"
|
|
274
|
-
)
|
|
283
|
+
msg = f"'{ae}={value}' does not look like a valid value"
|
|
275
284
|
raise PlotnineError(msg) from e
|
|
276
285
|
|
|
277
286
|
return data
|
plotnine/layer.py
CHANGED
|
@@ -257,6 +257,7 @@ class layer:
|
|
|
257
257
|
"""
|
|
258
258
|
self.geom.params["zorder"] = self.zorder
|
|
259
259
|
self.geom.params["raster"] = self.raster
|
|
260
|
+
self.geom.params["inherit_aes"] = self.inherit_aes
|
|
260
261
|
|
|
261
262
|
def compute_aesthetics(self, plot: ggplot):
|
|
262
263
|
"""
|
|
@@ -330,6 +331,7 @@ class layer:
|
|
|
330
331
|
|
|
331
332
|
self.geom.params.update(self.stat.params)
|
|
332
333
|
self.geom.setup_params(data)
|
|
334
|
+
self.geom.setup_aes_params(data)
|
|
333
335
|
data = self.geom.setup_data(data)
|
|
334
336
|
|
|
335
337
|
check_required_aesthetics(
|
plotnine/mapping/aes.py
CHANGED
|
@@ -8,7 +8,9 @@ from dataclasses import fields
|
|
|
8
8
|
from functools import cached_property
|
|
9
9
|
from typing import TYPE_CHECKING, Any, Dict
|
|
10
10
|
|
|
11
|
+
import numpy as np
|
|
11
12
|
import pandas as pd
|
|
13
|
+
from mizani._colors.utils import is_color_tuple
|
|
12
14
|
|
|
13
15
|
from ..iapi import labels_view
|
|
14
16
|
from .evaluation import after_stat, stage
|
|
@@ -538,23 +540,23 @@ def make_labels(mapping: dict[str, Any] | aes) -> labels_view:
|
|
|
538
540
|
)
|
|
539
541
|
|
|
540
542
|
|
|
541
|
-
|
|
543
|
+
class RepeatAesthetic:
|
|
542
544
|
"""
|
|
543
|
-
|
|
545
|
+
Repeat an Aeshetic a given number of times
|
|
544
546
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
value :
|
|
548
|
-
Value to check
|
|
549
|
-
ae :
|
|
550
|
-
Aesthetic name
|
|
547
|
+
The methods in this class know how to create sequences of aesthetics
|
|
548
|
+
whose values may not be scalar.
|
|
551
549
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
valid.
|
|
550
|
+
Some aesthetics may have valid values that are not scalar. e.g.
|
|
551
|
+
sequences. Inserting one of such a value in a dataframe as a column
|
|
552
|
+
would either lead to the wrong input or fail. The s
|
|
556
553
|
"""
|
|
557
|
-
|
|
554
|
+
|
|
555
|
+
@staticmethod
|
|
556
|
+
def linetype(value: Any, n: int) -> Sequence[Any]:
|
|
557
|
+
"""
|
|
558
|
+
Repeat linetypes
|
|
559
|
+
"""
|
|
558
560
|
named = {
|
|
559
561
|
"solid",
|
|
560
562
|
"dashed",
|
|
@@ -569,47 +571,75 @@ def is_valid_aesthetic(value: Any, ae: str) -> bool:
|
|
|
569
571
|
"",
|
|
570
572
|
}
|
|
571
573
|
if value in named:
|
|
572
|
-
return
|
|
574
|
+
return [value] * n
|
|
573
575
|
|
|
574
576
|
# tuple of the form (offset, (on, off, on, off, ...))
|
|
575
577
|
# e.g (0, (1, 2))
|
|
576
|
-
|
|
577
|
-
isinstance(value, tuple)
|
|
578
|
-
isinstance(value[0], int)
|
|
579
|
-
isinstance(value[1], tuple)
|
|
580
|
-
len(value[1]) % 2 == 0
|
|
581
|
-
all(isinstance(x, int) for x in value[1])
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
578
|
+
if (
|
|
579
|
+
isinstance(value, tuple)
|
|
580
|
+
and isinstance(value[0], int)
|
|
581
|
+
and isinstance(value[1], tuple)
|
|
582
|
+
and len(value[1]) % 2 == 0
|
|
583
|
+
and all(isinstance(x, int) for x in value[1])
|
|
584
|
+
):
|
|
585
|
+
return [value] * n
|
|
586
|
+
|
|
587
|
+
raise ValueError(f"{value} is not a known linetype.")
|
|
588
|
+
|
|
589
|
+
@staticmethod
|
|
590
|
+
def color(value: Any, n: int) -> Sequence[Any]:
|
|
591
|
+
"""
|
|
592
|
+
Repeat colors
|
|
593
|
+
"""
|
|
586
594
|
if isinstance(value, str):
|
|
587
|
-
return
|
|
595
|
+
return [value] * n
|
|
596
|
+
if is_color_tuple(value):
|
|
597
|
+
return [tuple(value)] * n
|
|
598
|
+
|
|
599
|
+
raise ValueError(f"{value} is not a known color.")
|
|
600
|
+
|
|
601
|
+
fill = color
|
|
588
602
|
|
|
603
|
+
@staticmethod
|
|
604
|
+
def shape(value: Any, n: int) -> Any:
|
|
605
|
+
"""
|
|
606
|
+
Repeat shapes
|
|
607
|
+
"""
|
|
608
|
+
if isinstance(value, str):
|
|
609
|
+
return [value] * n
|
|
589
610
|
# tuple of the form (numsides, style, angle)
|
|
590
611
|
# where style is in the range [0, 3]
|
|
591
612
|
# e.g (4, 1, 45)
|
|
592
|
-
|
|
593
|
-
isinstance(value, tuple)
|
|
594
|
-
all(isinstance(x, int) for x in value)
|
|
595
|
-
0 <= value[1] < 3
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if isinstance(value, (tuple, list)) and all(
|
|
604
|
-
0 <= x <= 1 for x in value
|
|
605
|
-
):
|
|
606
|
-
return True
|
|
607
|
-
return False
|
|
613
|
+
if (
|
|
614
|
+
isinstance(value, tuple)
|
|
615
|
+
and all(isinstance(x, int) for x in value)
|
|
616
|
+
and 0 <= value[1] < 3
|
|
617
|
+
):
|
|
618
|
+
return [value] * n
|
|
619
|
+
|
|
620
|
+
if is_shape_points(value):
|
|
621
|
+
return [tuple(value)] * n
|
|
622
|
+
|
|
623
|
+
raise ValueError(f"{value} is not a know shape.")
|
|
608
624
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
625
|
+
|
|
626
|
+
def is_shape_points(obj: Any) -> bool:
|
|
627
|
+
"""
|
|
628
|
+
Return True if obj is like Sequence[tuple[float, float]]
|
|
629
|
+
"""
|
|
630
|
+
|
|
631
|
+
def is_numeric(obj) -> bool:
|
|
632
|
+
"""
|
|
633
|
+
Return True if obj is a python or numpy float or integer
|
|
634
|
+
"""
|
|
635
|
+
return isinstance(obj, (float, int, np.floating, np.integer))
|
|
636
|
+
|
|
637
|
+
if not iter(obj):
|
|
638
|
+
return False
|
|
639
|
+
try:
|
|
640
|
+
return all(is_numeric(a) and is_numeric(b) for a, b in obj)
|
|
641
|
+
except TypeError:
|
|
642
|
+
return False
|
|
613
643
|
|
|
614
644
|
|
|
615
645
|
def has_groups(data: pd.DataFrame) -> bool:
|
|
@@ -396,7 +396,7 @@ class scale_continuous(
|
|
|
396
396
|
scaled = [na_value if x == "nan" else x for x in scaled]
|
|
397
397
|
else:
|
|
398
398
|
scaled[pd.isna(scaled)] = na_value
|
|
399
|
-
return scaled
|
|
399
|
+
return scaled
|
|
400
400
|
|
|
401
401
|
def get_breaks(
|
|
402
402
|
self, limits: Optional[tuple[float, float]] = None
|
|
@@ -206,7 +206,7 @@ class scale_discrete(
|
|
|
206
206
|
pal = np.asarray(pal, dtype=object)
|
|
207
207
|
idx = np.asarray(match(x, limits))
|
|
208
208
|
try:
|
|
209
|
-
pal_match = [pal[i] if i >= 0 else None for i in idx]
|
|
209
|
+
pal_match = [pal[i] if i >= 0 else None for i in idx]
|
|
210
210
|
except IndexError:
|
|
211
211
|
# Deal with missing data
|
|
212
212
|
# - Insert NaN where there is no match
|
|
@@ -155,7 +155,7 @@ def contour_lines(X, Y, Z, levels: int | FloatArrayLike):
|
|
|
155
155
|
level_values = []
|
|
156
156
|
start_pid = 1
|
|
157
157
|
for level in levels:
|
|
158
|
-
vertices, *_ = cgen.create_contour(level)
|
|
158
|
+
vertices, *_ = cgen.create_contour(level)
|
|
159
159
|
for pid, piece in enumerate(vertices, start=start_pid):
|
|
160
160
|
n = len(piece) # pyright: ignore
|
|
161
161
|
segments.append(piece)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotnine
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.0a4
|
|
4
4
|
Summary: A Grammar of Graphics for Python
|
|
5
5
|
Author-email: Hassan Kibirige <has2k1@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -48,7 +48,7 @@ Requires-Dist: matplotlib>=3.8.0
|
|
|
48
48
|
Requires-Dist: pandas>=2.2.0
|
|
49
49
|
Requires-Dist: mizani~=0.14.0
|
|
50
50
|
Requires-Dist: numpy>=1.23.5
|
|
51
|
-
Requires-Dist: scipy
|
|
51
|
+
Requires-Dist: scipy<1.16.0,>=1.8.0
|
|
52
52
|
Requires-Dist: statsmodels>=0.14.0
|
|
53
53
|
Provides-Extra: all
|
|
54
54
|
Requires-Dist: plotnine[extra]; extra == "all"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
plotnine/__init__.py,sha256=HrJhd65bnny1t-TawUgvApVj4p-gDZ0ftpr2NKZeW_s,10316
|
|
2
2
|
plotnine/animation.py,sha256=izJZ4Gy0cBHEBc8ehofsWSWOzZW8UEroy1Uvw86Igb0,7521
|
|
3
|
-
plotnine/doctools.py,sha256=
|
|
3
|
+
plotnine/doctools.py,sha256=JBF55q1MX2fXYQcGDpVrGPdlKf5OiQ5gyTdWhnM_IzU,14558
|
|
4
4
|
plotnine/exceptions.py,sha256=SgTxBHkV65HjGI3aFy2q1_lHP9HAdiuxVLN3U-PJWSQ,1616
|
|
5
5
|
plotnine/ggplot.py,sha256=xFj9iWAyBvnhitCrpgdNonQIqqjBQ2aDgkqpvHbH364,24823
|
|
6
6
|
plotnine/helpers.py,sha256=4R3KZmtGH46-kRNSGOA0JxZaLKBo0ge8Vnx1cDQ8_gI,966
|
|
7
7
|
plotnine/iapi.py,sha256=jNLmUSoh5g9kNdhOoXSqNcqOdd2-6xdWAmst-YGU41U,9095
|
|
8
8
|
plotnine/labels.py,sha256=3pOXth2Xma_qCqB_xXAGIkPQ9gcaUaaFEAsa5if1iR0,2830
|
|
9
|
-
plotnine/layer.py,sha256=
|
|
9
|
+
plotnine/layer.py,sha256=sUtzKTPnvkMuVFsNUFPkK9HUEcX7ohqv1EQV2KryS_c,16982
|
|
10
10
|
plotnine/options.py,sha256=j3zXv4wc3J4nOI_TqJ5s_abuifodt_UN8MR8M4i8UVA,3108
|
|
11
11
|
plotnine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
plotnine/qplot.py,sha256=BSAb4u5I7PaPGofkAgx7brdCNTjMZvC_TDGHVUZ35xM,7384
|
|
@@ -25,7 +25,7 @@ plotnine/_mpl/layout_manager/_engine.py,sha256=ESUvbLAlZApFbBi6w7gZA7S4guS0Rmrj-
|
|
|
25
25
|
plotnine/_mpl/layout_manager/_layout_items.py,sha256=3XRBl7xEdBKdhrexRmnVe7k919po6nkyE0q5Hx7j5cQ,29642
|
|
26
26
|
plotnine/_mpl/layout_manager/_layout_tree.py,sha256=O6U78CYOjSwS4lt56YF3YiOCXdxmV_oy3lYS4gMmzSc,26447
|
|
27
27
|
plotnine/_mpl/layout_manager/_spaces.py,sha256=ahBpKt-q1kVOTGiGliwl_DNB6pTEekAzA_7-GXwFlBk,35789
|
|
28
|
-
plotnine/_utils/__init__.py,sha256=
|
|
28
|
+
plotnine/_utils/__init__.py,sha256=czHi-uv4eIBCDf6td11bGA41PMXaJ5j7t-avx_JbYgY,30636
|
|
29
29
|
plotnine/_utils/context.py,sha256=HPQy_uyNXdS0s9URD7ZePyuc5hFU2XrRBLDTqRDLJzY,1708
|
|
30
30
|
plotnine/_utils/dev.py,sha256=0qgRbMhcd4dfuLuYxx0skocKAtfwHF02ntyILRBogbg,1629
|
|
31
31
|
plotnine/_utils/ipython.py,sha256=5Obr73xJ-4dzJEdBrFA8z9TXuxY7pIjKmzdTzWwnxNk,1884
|
|
@@ -66,10 +66,10 @@ plotnine/facets/labelling.py,sha256=JEuwERTK0IfmxTWHbl2nsGgxZ6xi0n2TTWT4_OSfQcQ,
|
|
|
66
66
|
plotnine/facets/layout.py,sha256=TIkMChA0wJWLKN31PH0czS6CN4pw3o--PF49LakJ2h4,8967
|
|
67
67
|
plotnine/facets/strips.py,sha256=-SWFaxqdzn-dnjx_Hxkuwd3kO-u_yreMLcMurm_IHqU,5688
|
|
68
68
|
plotnine/geoms/__init__.py,sha256=HEfhNmmNH4xm4rpXnFRXY4eLkJha3XPM72IIwVjv5Lc,2697
|
|
69
|
-
plotnine/geoms/annotate.py,sha256=
|
|
69
|
+
plotnine/geoms/annotate.py,sha256=T5RxepV55HVNzPfkq43BWxduNIZPslRfPD1yx4bJtoo,4165
|
|
70
70
|
plotnine/geoms/annotation_logticks.py,sha256=6iGdo5szck0_nXdHnvMaRMZuRbH8Tg87tJ_aan_frqg,8969
|
|
71
71
|
plotnine/geoms/annotation_stripes.py,sha256=4Cw7TJ4SZChm_ioqfiiku0cPNnLruGuAP-4vyRao-9Y,6080
|
|
72
|
-
plotnine/geoms/geom.py,sha256=
|
|
72
|
+
plotnine/geoms/geom.py,sha256=cjxzWTZiAMop9FuXWg5kqgo1lBEG2Uu6DzARjHOpBY4,17300
|
|
73
73
|
plotnine/geoms/geom_abline.py,sha256=6oxAJl_yFKKmf7OTHvACw6fg6kgJEN54hGKkyWOLr6o,3188
|
|
74
74
|
plotnine/geoms/geom_area.py,sha256=wvQ4nNvhJNN3nfn6Bv1gCARC6IWTjOjOfHPfSmg6Sxc,818
|
|
75
75
|
plotnine/geoms/geom_bar.py,sha256=SnqS4hPTfqXzdPh1U-kNuBg0LNX9_tQC9OKhIlB7cy0,1732
|
|
@@ -122,7 +122,7 @@ plotnine/guides/guides.py,sha256=cV7CwoYNrjkeaDHZ2AGcS2Dij5RpPovSiB-v47E7vhQ,154
|
|
|
122
122
|
plotnine/mapping/__init__.py,sha256=DLu9E0kwwuHxzTUenoVjCNTTdkWMwIDtkExLleBq1MI,205
|
|
123
123
|
plotnine/mapping/_env.py,sha256=ZXlTt2THRIcWb2WGk9fCpCMdVynlUX_BpG0Uwj7axi0,6072
|
|
124
124
|
plotnine/mapping/_eval_environment.py,sha256=PTrnnqrxMXqjt23t2NGRcU9i8Jie3ZaMe6W5aKtI7bI,2502
|
|
125
|
-
plotnine/mapping/aes.py,sha256=
|
|
125
|
+
plotnine/mapping/aes.py,sha256=eqNTBHqFnSBPoVNdrUB7pYM-ShlUTYvmwdQRXh9beV4,16717
|
|
126
126
|
plotnine/mapping/evaluation.py,sha256=kblTxVv3M4xIGnHyReUU0RtmmIN77Or2JBcci0nGGfE,5913
|
|
127
127
|
plotnine/plot_composition/__init__.py,sha256=ZJYpfVF158cQZ1zREXy6wHNJ4FbSmqWxIkHWZwX3QT8,148
|
|
128
128
|
plotnine/plot_composition/_compose.py,sha256=6UgXs6VBH0LIXW2uQlBQy-URh_mM948F5GOwN6IV734,12167
|
|
@@ -146,9 +146,9 @@ plotnine/scales/range.py,sha256=xBlFdAhthH1zKIJZDdkEyAA2kMZtyDorDFHKBMHKyAQ,1379
|
|
|
146
146
|
plotnine/scales/scale.py,sha256=T7oMfiXA2xOL_LQQIEKY_06VvXVfF-norNpc2gdTNNw,8078
|
|
147
147
|
plotnine/scales/scale_alpha.py,sha256=lYVZeaCC2pk-0-BoXnOeP0RdIbHYk6qo3DRClJrxTKo,2350
|
|
148
148
|
plotnine/scales/scale_color.py,sha256=6Cyjxml8Jn3EFiDY8IGvYM9_qacHvBQZFvbFh5Gyg8Q,14514
|
|
149
|
-
plotnine/scales/scale_continuous.py,sha256
|
|
149
|
+
plotnine/scales/scale_continuous.py,sha256=YMRjGh7QS644ajx5dVPJ9QTrWbTjmKt62MvVSFl3Y7U,16500
|
|
150
150
|
plotnine/scales/scale_datetime.py,sha256=OM9gfHKGkQIBrgqCEE00zUV0cMXXxTIS7wc9dYQZ6sE,3983
|
|
151
|
-
plotnine/scales/scale_discrete.py,sha256=
|
|
151
|
+
plotnine/scales/scale_discrete.py,sha256=UwAB0icMljH-eW6mK3g0YWAVzuE4P_91ZMYJhoMoMV4,9431
|
|
152
152
|
plotnine/scales/scale_identity.py,sha256=-PL9vJn0C_wOgrOQpqYSQbTWFSALoRPFzGXzebABTv8,2211
|
|
153
153
|
plotnine/scales/scale_linetype.py,sha256=pwLTmglN6d4bnChbuBi6HWbDP_nsE4viXD8CK6XKBPw,1373
|
|
154
154
|
plotnine/scales/scale_manual.py,sha256=oMnIfQNfxO4qw-gkBG3ikyuXdeoMgstRSdiibLc_DAA,4525
|
|
@@ -169,7 +169,7 @@ plotnine/stats/stat_bindot.py,sha256=FS-Axqhb-nMR9HK77BD-ElDHpsS8NaJKLMIff4-lDSU
|
|
|
169
169
|
plotnine/stats/stat_boxplot.py,sha256=5PvTTig5kAZQjenYL-158tjnzRnRUcnJpJL5qOdv9WI,5997
|
|
170
170
|
plotnine/stats/stat_count.py,sha256=P560-9Lm6FWUvL5bGASIBxY3vQnbcZrU4CYlBdZpE3Y,1928
|
|
171
171
|
plotnine/stats/stat_density.py,sha256=1TyOIiAaOaZesPcqIsnaVk14by0cKu6b7d7r-a5ZZSI,10346
|
|
172
|
-
plotnine/stats/stat_density_2d.py,sha256=
|
|
172
|
+
plotnine/stats/stat_density_2d.py,sha256=XSyE78IJwLLH4G5H7UD7ZrmknmaGCEMUHwvwNYmYVLQ,5647
|
|
173
173
|
plotnine/stats/stat_ecdf.py,sha256=BdeisCWzDnuPMc3vBgZqpDsXCKy8ZfoSRwFPOQlgksM,1630
|
|
174
174
|
plotnine/stats/stat_ellipse.py,sha256=NMr22TQMfVDZejIKvw1UWcB1NJptTlg6-qRf8d8EzJE,7570
|
|
175
175
|
plotnine/stats/stat_function.py,sha256=AcP_wUu063fA8RAjc7AoFuVQmLdlsuEvP6m8AuTm9HY,3123
|
|
@@ -211,8 +211,8 @@ plotnine/themes/elements/element_line.py,sha256=xF6xW-iA66YEP_fN7ooqaYry8_8qZT-e
|
|
|
211
211
|
plotnine/themes/elements/element_rect.py,sha256=w5cLH-Sr4cTRXVdkRiu8kBqFt3TXHhIb1MUITfi89gE,1767
|
|
212
212
|
plotnine/themes/elements/element_text.py,sha256=8yhwBa9s9JKCtBcqcBNybbCGK6ieDnZv4SHiC4Sy2qc,6255
|
|
213
213
|
plotnine/themes/elements/margin.py,sha256=jMHe-UKHHer_VYwAVDC-Tz2-AP_4YDuXPTWAuacoqgU,4080
|
|
214
|
-
plotnine-0.15.
|
|
215
|
-
plotnine-0.15.
|
|
216
|
-
plotnine-0.15.
|
|
217
|
-
plotnine-0.15.
|
|
218
|
-
plotnine-0.15.
|
|
214
|
+
plotnine-0.15.0a4.dist-info/licenses/LICENSE,sha256=GY4tQiUd17Tq3wWR42Zs9MRTFOTf6ahIXhZTcwAdOeU,1082
|
|
215
|
+
plotnine-0.15.0a4.dist-info/METADATA,sha256=MCVzMIfRSdwYyq2UrgdS74Zc8QiMo9pp8GiwCVFZXCo,9407
|
|
216
|
+
plotnine-0.15.0a4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
217
|
+
plotnine-0.15.0a4.dist-info/top_level.txt,sha256=t340Mbko1ZbmvYPkQ81dIiPHcaQdTUszYz-bWUpr8ys,9
|
|
218
|
+
plotnine-0.15.0a4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|