dataplot 0.1.6__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.
- dataplot/__init__.py +34 -0
- dataplot/_typing.py +211 -0
- dataplot/artist/__init__.py +24 -0
- dataplot/artist/base.py +78 -0
- dataplot/artist/corrmap.py +57 -0
- dataplot/artist/histogram.py +89 -0
- dataplot/artist/ksplot.py +42 -0
- dataplot/artist/linechart.py +62 -0
- dataplot/artist/ppplot.py +41 -0
- dataplot/artist/qqplot.py +92 -0
- dataplot/artist/scatterchart.py +59 -0
- dataplot/container.py +203 -0
- dataplot/core.py +202 -0
- dataplot/dataset.py +968 -0
- dataplot/setting.py +232 -0
- dataplot/utils/__init__.py +6 -0
- dataplot/utils/math.py +80 -0
- dataplot/utils/multi.py +269 -0
- dataplot-0.1.6.dist-info/METADATA +100 -0
- dataplot-0.1.6.dist-info/RECORD +22 -0
- dataplot-0.1.6.dist-info/WHEEL +4 -0
- dataplot-0.1.6.dist-info/licenses/LICENSE +28 -0
dataplot/__init__.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
# dataplot
|
|
3
|
+
Provides plotting tools useful in datascience.
|
|
4
|
+
|
|
5
|
+
## See Also
|
|
6
|
+
### Github repository
|
|
7
|
+
* https://github.com/Chitaoji/dataplot/
|
|
8
|
+
|
|
9
|
+
### PyPI project
|
|
10
|
+
* https://pypi.org/project/dataplot/
|
|
11
|
+
|
|
12
|
+
## License
|
|
13
|
+
This project falls under the BSD 3-Clause License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import lazyr
|
|
18
|
+
|
|
19
|
+
with lazyr.setverbose(0):
|
|
20
|
+
lazyr.register("pandas")
|
|
21
|
+
lazyr.register("scipy.stats")
|
|
22
|
+
lazyr.register("seaborn")
|
|
23
|
+
|
|
24
|
+
from . import container, core, dataset, setting
|
|
25
|
+
from .container import *
|
|
26
|
+
from .core import *
|
|
27
|
+
from .dataset import *
|
|
28
|
+
from .setting import *
|
|
29
|
+
|
|
30
|
+
__all__: list[str] = []
|
|
31
|
+
__all__.extend(core.__all__)
|
|
32
|
+
__all__.extend(setting.__all__)
|
|
33
|
+
__all__.extend(container.__all__)
|
|
34
|
+
__all__.extend(dataset.__all__)
|
dataplot/_typing.py
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains typing classes.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is not intended to be imported at runtime.
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TYPE_CHECKING, Literal, NotRequired, Optional, TypedDict, TypeVar
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .setting import PlotSettable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
PlotSettableVar = TypeVar("PlotSettableVar", bound="PlotSettable")
|
|
15
|
+
DefaultVar = TypeVar("DefaultVar")
|
|
16
|
+
StyleName = Literal[
|
|
17
|
+
"Solarize_Light2",
|
|
18
|
+
"_classic_test_patch",
|
|
19
|
+
"_mpl-gallery",
|
|
20
|
+
"_mpl-gallery-nogrid",
|
|
21
|
+
"bmh",
|
|
22
|
+
"classic",
|
|
23
|
+
"dark_background",
|
|
24
|
+
"fast",
|
|
25
|
+
"fivethirtyeight",
|
|
26
|
+
"ggplot",
|
|
27
|
+
"grayscale",
|
|
28
|
+
"seaborn-v0_8",
|
|
29
|
+
"seaborn-v0_8-bright",
|
|
30
|
+
"seaborn-v0_8-colorblind",
|
|
31
|
+
"seaborn-v0_8-dark",
|
|
32
|
+
"seaborn-v0_8-dark-palette",
|
|
33
|
+
"seaborn-v0_8-darkgrid",
|
|
34
|
+
"seaborn-v0_8-deep",
|
|
35
|
+
"seaborn-v0_8-muted",
|
|
36
|
+
"seaborn-v0_8-notebook",
|
|
37
|
+
"seaborn-v0_8-paper",
|
|
38
|
+
"seaborn-v0_8-pastel",
|
|
39
|
+
"seaborn-v0_8-poster",
|
|
40
|
+
"seaborn-v0_8-talk",
|
|
41
|
+
"seaborn-v0_8-ticks",
|
|
42
|
+
"seaborn-v0_8-white",
|
|
43
|
+
"seaborn-v0_8-whitegrid",
|
|
44
|
+
"tableau-colorblind10",
|
|
45
|
+
]
|
|
46
|
+
LegendLoc = Literal[
|
|
47
|
+
"best",
|
|
48
|
+
"upper right",
|
|
49
|
+
"upper left",
|
|
50
|
+
"lower left",
|
|
51
|
+
"lower right",
|
|
52
|
+
"right",
|
|
53
|
+
"center left",
|
|
54
|
+
"center right",
|
|
55
|
+
"lower center",
|
|
56
|
+
"upper center",
|
|
57
|
+
"center",
|
|
58
|
+
]
|
|
59
|
+
FontSize = Literal[
|
|
60
|
+
"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
|
|
61
|
+
]
|
|
62
|
+
FontWeight = Literal[
|
|
63
|
+
"ultralight",
|
|
64
|
+
"light",
|
|
65
|
+
"normal",
|
|
66
|
+
"regular",
|
|
67
|
+
"book",
|
|
68
|
+
"medium",
|
|
69
|
+
"roman",
|
|
70
|
+
"semibold",
|
|
71
|
+
"demibold",
|
|
72
|
+
"demi",
|
|
73
|
+
"bold",
|
|
74
|
+
"heavy",
|
|
75
|
+
"extra bold",
|
|
76
|
+
"black",
|
|
77
|
+
]
|
|
78
|
+
FontStyleName = Literal["normal", "italic", "oblique"]
|
|
79
|
+
ColorId = (
|
|
80
|
+
Literal["b", "g", "r", "c", "m", "y", "k", "w"]
|
|
81
|
+
| Literal["C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9"]
|
|
82
|
+
)
|
|
83
|
+
VerticalAlignment = Literal["baseline", "bottom", "center", "center_baseline", "top"]
|
|
84
|
+
HorizontalAlignment = Literal["left", "center", "right"]
|
|
85
|
+
DistName = Literal["normal", "expon"]
|
|
86
|
+
SettingKey = Literal[
|
|
87
|
+
"title",
|
|
88
|
+
"xlabel",
|
|
89
|
+
"ylabel",
|
|
90
|
+
"alpha",
|
|
91
|
+
"dpi",
|
|
92
|
+
"grid",
|
|
93
|
+
"grid_alpha",
|
|
94
|
+
"style",
|
|
95
|
+
"figsize",
|
|
96
|
+
"fontdict",
|
|
97
|
+
"legend_loc",
|
|
98
|
+
"subplots_adjust",
|
|
99
|
+
]
|
|
100
|
+
ResampleRule = Literal["head", "tail", "random"]
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class SettingDict(TypedDict):
|
|
104
|
+
"""
|
|
105
|
+
Dict of keyword-arguments for `._set()`.
|
|
106
|
+
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
title: NotRequired[Optional[str]]
|
|
110
|
+
xlabel: NotRequired[Optional[str]]
|
|
111
|
+
ylabel: NotRequired[Optional[str]]
|
|
112
|
+
alpha: NotRequired[Optional[float]]
|
|
113
|
+
dpi: NotRequired[Optional[float]]
|
|
114
|
+
grid: NotRequired[Optional[bool]]
|
|
115
|
+
grid_alpha: NotRequired[Optional[float]]
|
|
116
|
+
style: NotRequired[Optional[StyleName]]
|
|
117
|
+
figsize: NotRequired[Optional[tuple[int, int]]]
|
|
118
|
+
fontdict: NotRequired[Optional["FontDict"]]
|
|
119
|
+
legend_loc: NotRequired[Optional[str]]
|
|
120
|
+
format_label: NotRequired[Optional[bool]]
|
|
121
|
+
subplots_adjust: NotRequired[Optional["SubplotDict"]]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class FigureSettingDict(TypedDict):
|
|
125
|
+
"""
|
|
126
|
+
Dict of keyword-arguments for `.set_figure()`.
|
|
127
|
+
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
title: NotRequired[Optional[str]]
|
|
131
|
+
dpi: NotRequired[Optional[float]]
|
|
132
|
+
style: NotRequired[Optional[StyleName]]
|
|
133
|
+
figsize: NotRequired[Optional[tuple[int, int]]]
|
|
134
|
+
fontdict: NotRequired[Optional["FontDict"]]
|
|
135
|
+
subplots_adjust: NotRequired[Optional["SubplotDict"]]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class AxesSettingDict(TypedDict):
|
|
139
|
+
"""
|
|
140
|
+
Dict of keyword-arguments for `.set_axes()`.
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
title: NotRequired[Optional[str]]
|
|
145
|
+
xlabel: NotRequired[Optional[str]]
|
|
146
|
+
ylabel: NotRequired[Optional[str]]
|
|
147
|
+
alpha: NotRequired[Optional[float]]
|
|
148
|
+
grid: NotRequired[Optional[bool]]
|
|
149
|
+
grid_alpha: NotRequired[Optional[float]]
|
|
150
|
+
fontdict: NotRequired[Optional["FontDict"]]
|
|
151
|
+
legend_loc: NotRequired[Optional[LegendLoc]]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class FontDict(TypedDict):
|
|
155
|
+
"""
|
|
156
|
+
A dictionary controlling the appearance of the title text.
|
|
157
|
+
|
|
158
|
+
Unset parameters are left unmodified; initial values are given by
|
|
159
|
+
`matplotlib.rcParams`.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
fontsize : float | FontSizeStr, optional
|
|
164
|
+
The font size.
|
|
165
|
+
fontweight : float | FontWeightStr, optional
|
|
166
|
+
The font weight. If a float, should be in range 0-1000.
|
|
167
|
+
fontstyle : FontStyleStr, optional
|
|
168
|
+
The font style.
|
|
169
|
+
color : ColorStr, optional
|
|
170
|
+
The font color.
|
|
171
|
+
verticalalignment : VerticalAlignmentStr, optional
|
|
172
|
+
The vertical alignment relative to the anchor point.
|
|
173
|
+
horizontalalignment : HorizontalAlignmentStr, optional
|
|
174
|
+
The horizontal alignment relative to the anchor point.
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
fontsize: NotRequired[float | FontSize]
|
|
179
|
+
fontweight: NotRequired[float | FontWeight]
|
|
180
|
+
fontstyle: NotRequired[FontStyleName]
|
|
181
|
+
color: NotRequired[ColorId]
|
|
182
|
+
verticalalignment: NotRequired[VerticalAlignment]
|
|
183
|
+
horizontalalignment: NotRequired[HorizontalAlignment]
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class SubplotDict(TypedDict):
|
|
187
|
+
"""
|
|
188
|
+
A dictionary controlling the subplot layout parameters.
|
|
189
|
+
|
|
190
|
+
Unset parameters are left unmodified; initial values are given by
|
|
191
|
+
`matplotlib.rcParams`, whose recommended values are {"left": 0.125,
|
|
192
|
+
"bottom": 0.11, "right": 0.9, "top": 0.88, "wspace": 0.2, "hspace":
|
|
193
|
+
0.2}.
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
left / right / bottom / top : float, optional
|
|
198
|
+
The position of the left / right / bottom / top edge of the
|
|
199
|
+
subplots, as a fraction of the figure width.
|
|
200
|
+
wspace / hspace : float, optional
|
|
201
|
+
The width / height of the padding between subplots, as a fraction
|
|
202
|
+
of the average Axes width / height.
|
|
203
|
+
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
left: NotRequired[float]
|
|
207
|
+
bottom: NotRequired[float]
|
|
208
|
+
right: NotRequired[float]
|
|
209
|
+
top: NotRequired[float]
|
|
210
|
+
wspace: NotRequired[float]
|
|
211
|
+
hspace: NotRequired[float]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains artists.
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from . import base, corrmap, histogram, ksplot, linechart, ppplot, qqplot, scatterchart
|
|
7
|
+
from .base import *
|
|
8
|
+
from .corrmap import *
|
|
9
|
+
from .histogram import *
|
|
10
|
+
from .ksplot import *
|
|
11
|
+
from .linechart import *
|
|
12
|
+
from .ppplot import *
|
|
13
|
+
from .qqplot import *
|
|
14
|
+
from .scatterchart import *
|
|
15
|
+
|
|
16
|
+
__all__: list[str] = []
|
|
17
|
+
__all__.extend(base.__all__)
|
|
18
|
+
__all__.extend(corrmap.__all__)
|
|
19
|
+
__all__.extend(histogram.__all__)
|
|
20
|
+
__all__.extend(ksplot.__all__)
|
|
21
|
+
__all__.extend(linechart.__all__)
|
|
22
|
+
__all__.extend(ppplot.__all__)
|
|
23
|
+
__all__.extend(qqplot.__all__)
|
|
24
|
+
__all__.extend(scatterchart.__all__)
|
dataplot/artist/base.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains the core of artist: Artist, Plotter.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is private. All functions and objects are available in the main
|
|
5
|
+
`dataplot` namespace - use that instead.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from collections import Counter
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
from validating import attr, dataclass
|
|
14
|
+
|
|
15
|
+
from ..container import FigWrapper
|
|
16
|
+
from ..setting import PlotSettable
|
|
17
|
+
from ..utils.multi import MultiObject, multiple
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from ..container import AxesWrapper
|
|
21
|
+
|
|
22
|
+
__all__ = ["Artist", "Plotter"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(validate_methods=True)
|
|
26
|
+
class Artist(PlotSettable):
|
|
27
|
+
"""
|
|
28
|
+
Paint the desired images on an axes.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
plotter : Plotter
|
|
33
|
+
Painting tool.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
plotter: "Plotter | MultiObject"
|
|
38
|
+
ax: Optional["AxesWrapper"] = attr(default=None, repr=False)
|
|
39
|
+
|
|
40
|
+
def __repr__(self) -> str:
|
|
41
|
+
self.paint(self.ax)
|
|
42
|
+
names = (x.__class__.__name__ for x in multiple(self.plotter))
|
|
43
|
+
s = ", ".join(f"{i} {x}s" for x, i in Counter(names).items())
|
|
44
|
+
return f"<{self.__class__.__name__} with {s}>"
|
|
45
|
+
|
|
46
|
+
def paint(self, ax: Optional["AxesWrapper"] = None) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Paint on the axes.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
ax : AxesWrapper, optional
|
|
53
|
+
Specifies the axes-wrapper on which the plot should be painted,
|
|
54
|
+
by default None.
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
with self.customize(FigWrapper, 1, 1, active := ax is None) as fig:
|
|
58
|
+
self.plotter.paint(fig.axes[0] if active else ax)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(init=False, validate_methods=True)
|
|
62
|
+
class Plotter(PlotSettable):
|
|
63
|
+
"""
|
|
64
|
+
Painting tool used by Artist - user can ignore this.
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
data: Optional[np.ndarray] = attr(repr=False, default=None, init=False)
|
|
69
|
+
label: Optional[str] = attr(default=None, init=False)
|
|
70
|
+
|
|
71
|
+
def paint(
|
|
72
|
+
self,
|
|
73
|
+
ax: "AxesWrapper",
|
|
74
|
+
*,
|
|
75
|
+
__multi_prev_returned__: Any = None,
|
|
76
|
+
__multi_is_final__: bool = True,
|
|
77
|
+
) -> Any:
|
|
78
|
+
"""Paint."""
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains a plotter class: CorrMap.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is private. All functions and objects are available in the main
|
|
5
|
+
`dataplot` namespace - use that instead.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING, Optional
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
import pandas as pd
|
|
13
|
+
import seaborn as sns
|
|
14
|
+
from validating import dataclass
|
|
15
|
+
|
|
16
|
+
from .base import Plotter
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from ..container import AxesWrapper
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ["CorrMap"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(validate_methods=True)
|
|
26
|
+
class CorrMap(Plotter):
|
|
27
|
+
"""
|
|
28
|
+
A plotter class that creates a correlation heatmap.
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
annot: bool
|
|
33
|
+
|
|
34
|
+
def paint(
|
|
35
|
+
self,
|
|
36
|
+
ax: "AxesWrapper",
|
|
37
|
+
*,
|
|
38
|
+
__multi_prev_returned__: Optional[tuple[list[np.ndarray], list[str]]] = None,
|
|
39
|
+
__multi_is_final__: bool = True,
|
|
40
|
+
) -> tuple[list[np.ndarray], list[str]]:
|
|
41
|
+
if __multi_prev_returned__ is None:
|
|
42
|
+
arrays, labels = [], []
|
|
43
|
+
else:
|
|
44
|
+
arrays, labels = __multi_prev_returned__
|
|
45
|
+
arrays.append(self.data)
|
|
46
|
+
labels.append(self.label)
|
|
47
|
+
if __multi_is_final__:
|
|
48
|
+
ax.set_default(title="Correlation Heatmap")
|
|
49
|
+
ax.load(self.settings)
|
|
50
|
+
self.__plot(ax, arrays, labels)
|
|
51
|
+
return arrays, labels
|
|
52
|
+
|
|
53
|
+
def __plot(
|
|
54
|
+
self, ax: "AxesWrapper", arrays: list[np.ndarray], labels: list[str]
|
|
55
|
+
) -> None:
|
|
56
|
+
corr = pd.DataFrame(arrays, index=labels).T.corr()
|
|
57
|
+
sns.heatmap(corr, ax=ax.ax, annot=self.annot)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains a plotter class: Histogram.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is private. All functions and objects are available in the main
|
|
5
|
+
`dataplot` namespace - use that instead.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING, Optional
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
from scipy import stats
|
|
13
|
+
from validating import dataclass
|
|
14
|
+
|
|
15
|
+
from .base import Plotter
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from ..container import AxesWrapper
|
|
19
|
+
|
|
20
|
+
__all__ = ["Histogram"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(validate_methods=True)
|
|
24
|
+
class Histogram(Plotter):
|
|
25
|
+
"""
|
|
26
|
+
A plotter class that creates a histogram.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
bins: int | list[float]
|
|
31
|
+
fit: bool
|
|
32
|
+
density: bool
|
|
33
|
+
log: bool
|
|
34
|
+
same_bin: bool
|
|
35
|
+
stats: bool
|
|
36
|
+
|
|
37
|
+
def paint(
|
|
38
|
+
self,
|
|
39
|
+
ax: "AxesWrapper",
|
|
40
|
+
*,
|
|
41
|
+
__multi_prev_returned__: Optional[tuple[str, np.ndarray]] = None,
|
|
42
|
+
__multi_is_final__: bool = True,
|
|
43
|
+
) -> list[float]:
|
|
44
|
+
ax.set_default(
|
|
45
|
+
title="Histogram",
|
|
46
|
+
alpha=0.8,
|
|
47
|
+
xlabel="value",
|
|
48
|
+
ylabel="density" if self.density else "count",
|
|
49
|
+
)
|
|
50
|
+
ax.load(self.settings)
|
|
51
|
+
if __multi_prev_returned__ is None:
|
|
52
|
+
xlabel, bins = ax.settings.xlabel, None
|
|
53
|
+
else:
|
|
54
|
+
xlabel, bins = __multi_prev_returned__
|
|
55
|
+
ds, new_bins = self.__hist(
|
|
56
|
+
ax, bins=self.bins if (bins is None or not self.same_bin) else bins
|
|
57
|
+
)
|
|
58
|
+
if self.stats:
|
|
59
|
+
xlabel += "\n" + ds
|
|
60
|
+
if __multi_is_final__:
|
|
61
|
+
ax.set_axes(xlabel=xlabel)
|
|
62
|
+
return (xlabel, new_bins)
|
|
63
|
+
|
|
64
|
+
def __hist(
|
|
65
|
+
self, ax: "AxesWrapper", bins: int | list[float] = 100
|
|
66
|
+
) -> tuple[str, np.ndarray]:
|
|
67
|
+
_, bin_list, _ = ax.ax.hist(
|
|
68
|
+
self.data,
|
|
69
|
+
bins=bins,
|
|
70
|
+
density=self.density,
|
|
71
|
+
log=self.log,
|
|
72
|
+
alpha=ax.settings.alpha,
|
|
73
|
+
label=self.label,
|
|
74
|
+
)
|
|
75
|
+
mean, std = np.nanmean(self.data), np.nanstd(self.data)
|
|
76
|
+
skew: float = stats.skew(self.data, bias=False, nan_policy="omit")
|
|
77
|
+
kurt: float = stats.kurtosis(self.data, bias=False, nan_policy="omit")
|
|
78
|
+
if self.fit and self.density:
|
|
79
|
+
ax.ax.plot(
|
|
80
|
+
bin_list,
|
|
81
|
+
stats.norm.pdf(bin_list, mean, std),
|
|
82
|
+
alpha=ax.settings.alpha,
|
|
83
|
+
label=f"{self.label} · fit",
|
|
84
|
+
)
|
|
85
|
+
return (
|
|
86
|
+
f"{self.label}: mean={mean:.3f}, std={std:.3f}, skew={skew:.3f}, "
|
|
87
|
+
f"kurt={kurt:.3f}",
|
|
88
|
+
bin_list,
|
|
89
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains a plotter class: KSPlot.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is private. All functions and objects are available in the main
|
|
5
|
+
`dataplot` namespace - use that instead.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from validating import dataclass
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from ..utils.math import get_quantile
|
|
13
|
+
from .qqplot import QQPlot
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ..container import AxesWrapper
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
__all__ = ["KSPlot"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(validate_methods=True)
|
|
23
|
+
class KSPlot(QQPlot):
|
|
24
|
+
"""
|
|
25
|
+
A plotter class that creates a K-S plot.
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def paint(self, ax: "AxesWrapper", **_) -> None:
|
|
30
|
+
ax.set_default(
|
|
31
|
+
title="Kolmogorov-Smirnov Plot",
|
|
32
|
+
xlabel="value",
|
|
33
|
+
ylabel="cummulative probability",
|
|
34
|
+
)
|
|
35
|
+
ax.load(self.settings)
|
|
36
|
+
self.__plot(ax)
|
|
37
|
+
|
|
38
|
+
def __plot(self, ax: "AxesWrapper") -> None:
|
|
39
|
+
xlabel, p, q1 = self._generate_dist()
|
|
40
|
+
q2 = get_quantile(self.data, p)
|
|
41
|
+
ax.ax.plot(q1, p, self.fmt, label=xlabel)
|
|
42
|
+
ax.ax.plot(q2, p, self.fmt, label=self.label)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains a plotter class: LineChart.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is private. All functions and objects are available in the main
|
|
5
|
+
`dataplot` namespace - use that instead.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from validating import dataclass
|
|
10
|
+
from typing import TYPE_CHECKING, Optional
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
from ..setting import PlotSettable
|
|
15
|
+
from .base import Plotter
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from ..container import AxesWrapper
|
|
19
|
+
from ..dataset import PlotDataSet
|
|
20
|
+
|
|
21
|
+
__all__ = ["LineChart"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(validate_methods=True)
|
|
25
|
+
class LineChart(Plotter):
|
|
26
|
+
"""
|
|
27
|
+
A plotter class that creates a line chart.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
xticks: Optional["np.ndarray | PlotDataSet"]
|
|
32
|
+
fmt: str
|
|
33
|
+
scatter: bool
|
|
34
|
+
sorted: bool
|
|
35
|
+
|
|
36
|
+
def paint(self, ax: "AxesWrapper", **_) -> None:
|
|
37
|
+
ax.set_default(title="Line Chart")
|
|
38
|
+
ax.load(self.settings)
|
|
39
|
+
self.__plot(ax)
|
|
40
|
+
|
|
41
|
+
def __plot(self, ax: "AxesWrapper") -> None:
|
|
42
|
+
if isinstance(self.xticks, PlotSettable):
|
|
43
|
+
xticks = self.xticks.data
|
|
44
|
+
else:
|
|
45
|
+
xticks = self.xticks
|
|
46
|
+
if xticks is None:
|
|
47
|
+
xticks = range(len(self.data))
|
|
48
|
+
elif (len_t := len(xticks)) != (len_d := len(self.data)):
|
|
49
|
+
raise ValueError(
|
|
50
|
+
"x-ticks and data must have the same length, but have "
|
|
51
|
+
f"lengths {len_t} and {len_d}"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
if self.sorted:
|
|
55
|
+
paired = sorted(zip(xticks, self.data, strict=True), key=lambda pair: pair[0])
|
|
56
|
+
xticks, data = zip(*paired, strict=True)
|
|
57
|
+
else:
|
|
58
|
+
data = self.data
|
|
59
|
+
|
|
60
|
+
ax.ax.plot(xticks, data, self.fmt, label=self.label)
|
|
61
|
+
if self.scatter:
|
|
62
|
+
ax.ax.scatter(xticks, data, zorder=2.0)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains a plotter class: PPPlot.
|
|
3
|
+
|
|
4
|
+
NOTE: this module is private. All functions and objects are available in the main
|
|
5
|
+
`dataplot` namespace - use that instead.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from validating import dataclass
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from ..utils.math import get_prob
|
|
13
|
+
from .qqplot import QQPlot
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ..container import AxesWrapper
|
|
17
|
+
|
|
18
|
+
__all__ = ["PPPlot"]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(validate_methods=True)
|
|
22
|
+
class PPPlot(QQPlot):
|
|
23
|
+
"""
|
|
24
|
+
A plotter class that creates a P-P plot.
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def paint(self, ax: "AxesWrapper", **_) -> None:
|
|
29
|
+
ax.set_default(
|
|
30
|
+
title="Probability-Probability Plot",
|
|
31
|
+
xlabel="cumulative probility",
|
|
32
|
+
ylabel="cumulative probility",
|
|
33
|
+
)
|
|
34
|
+
ax.load(self.settings)
|
|
35
|
+
self.__plot(ax)
|
|
36
|
+
|
|
37
|
+
def __plot(self, ax: "AxesWrapper") -> None:
|
|
38
|
+
xlabel, p1, q = self._generate_dist()
|
|
39
|
+
p2 = get_prob(self.data, q)
|
|
40
|
+
ax.ax.plot(p1, p2, self.fmt, zorder=2.1, label=f"{self.label} & {xlabel}")
|
|
41
|
+
self._plot_fitted_line(ax, p1, p2)
|