rsplotlib 0.3.5__cp39-cp39-win_amd64.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.
- rsplotlib/__init__.py +101 -0
- rsplotlib/_font_resolver.py +167 -0
- rsplotlib/cm.py +15 -0
- rsplotlib/collections.py +35 -0
- rsplotlib/colors.py +186 -0
- rsplotlib/core/__init__.py +2 -0
- rsplotlib/core/api.py +771 -0
- rsplotlib/dates.py +85 -0
- rsplotlib/figure/__init__.py +2 -0
- rsplotlib/figure/_defaults.py +13 -0
- rsplotlib/gridspec.py +6 -0
- rsplotlib/layout/__init__.py +2 -0
- rsplotlib/layout/gridspec.py +161 -0
- rsplotlib/patches.py +54 -0
- rsplotlib/path.py +4 -0
- rsplotlib/pylab.py +22 -0
- rsplotlib/pyplot.py +3772 -0
- rsplotlib/rsplotlib.cp39-win_amd64.pyd +0 -0
- rsplotlib/text.py +18 -0
- rsplotlib/ticker.py +6 -0
- rsplotlib/ticks/__init__.py +2 -0
- rsplotlib/ticks/ticker.py +269 -0
- rsplotlib/utils/__init__.py +2 -0
- rsplotlib/utils/_font_resolver.py +34 -0
- rsplotlib/utils/_rcparams.py +103 -0
- rsplotlib/utils/style.py +103 -0
- rsplotlib-0.3.5.dist-info/METADATA +112 -0
- rsplotlib-0.3.5.dist-info/RECORD +31 -0
- rsplotlib-0.3.5.dist-info/WHEEL +4 -0
- rsplotlib-0.3.5.dist-info/licenses/LICENSE +21 -0
- rsplotlib-0.3.5.dist-info/sboms/rsplotlib.cyclonedx.json +2250 -0
rsplotlib/dates.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""rsplotlib.dates - Matplotlib dates 兼容接口 (子集)。
|
|
2
|
+
|
|
3
|
+
提供日期刻度格式化器 ConciseDateFormatter,兼容 matplotlib.dates 的常用 API。
|
|
4
|
+
日期数值沿用 matplotlib 约定:浮点数表示自 1970-01-01 (UTC) 起的天数。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import datetime as _datetime
|
|
8
|
+
|
|
9
|
+
from .ticks.ticker import Formatter
|
|
10
|
+
|
|
11
|
+
# matplotlib 自 3.3 起默认纪元为 1970-01-01
|
|
12
|
+
_EPOCH = _datetime.datetime(1970, 1, 1)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def num2date(x):
|
|
16
|
+
"""将 matplotlib 日期数值 (自纪元起的天数) 转为 datetime。"""
|
|
17
|
+
return _EPOCH + _datetime.timedelta(days=float(x))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ConciseDateFormatter(Formatter):
|
|
21
|
+
"""紧凑日期格式化器,兼容 matplotlib.dates.ConciseDateFormatter。
|
|
22
|
+
|
|
23
|
+
根据刻度跨度自动选择合适的日期/时间粒度,尽量少地重复上层信息
|
|
24
|
+
(年/月/日),产出简洁的刻度标签。
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
locator: 关联的刻度定位器 (与 matplotlib 一致,可选用于确定跨度)。
|
|
28
|
+
tz, formats, offset_formats, zero_formats, show_offset, usetex:
|
|
29
|
+
为兼容 matplotlib 签名而接受,当前实现下部分参数不生效。
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, locator=None, tz=None, formats=None,
|
|
33
|
+
offset_formats=None, zero_formats=None, show_offset=True,
|
|
34
|
+
*, usetex=None):
|
|
35
|
+
self._locator = locator
|
|
36
|
+
self._tz = tz
|
|
37
|
+
self.formats = formats
|
|
38
|
+
self.zero_formats = zero_formats
|
|
39
|
+
self.offset_formats = offset_formats
|
|
40
|
+
self.show_offset = show_offset
|
|
41
|
+
self._usetex = usetex
|
|
42
|
+
self.offset_string = ''
|
|
43
|
+
|
|
44
|
+
def _to_datetime(self, value):
|
|
45
|
+
if isinstance(value, _datetime.datetime):
|
|
46
|
+
return value
|
|
47
|
+
if isinstance(value, _datetime.date):
|
|
48
|
+
return _datetime.datetime(value.year, value.month, value.day)
|
|
49
|
+
if isinstance(value, str):
|
|
50
|
+
return None
|
|
51
|
+
return num2date(value)
|
|
52
|
+
|
|
53
|
+
def _choose_scale(self, values):
|
|
54
|
+
"""根据刻度跨度选择格式粒度。返回 strftime 模式。"""
|
|
55
|
+
dts = [self._to_datetime(v) for v in values]
|
|
56
|
+
dts = [d for d in dts if d is not None]
|
|
57
|
+
if len(dts) < 2:
|
|
58
|
+
return '%b %d'
|
|
59
|
+
span = max(dts) - min(dts)
|
|
60
|
+
secs = abs(span.total_seconds())
|
|
61
|
+
if secs > 365 * 24 * 3600:
|
|
62
|
+
return '%Y'
|
|
63
|
+
if secs > 30 * 24 * 3600:
|
|
64
|
+
return '%Y-%m'
|
|
65
|
+
if secs > 24 * 3600:
|
|
66
|
+
return '%b %d'
|
|
67
|
+
if secs > 3600:
|
|
68
|
+
return '%H:%M'
|
|
69
|
+
return '%H:%M:%S'
|
|
70
|
+
|
|
71
|
+
def format_ticks(self, values):
|
|
72
|
+
fmt = self._choose_scale(values)
|
|
73
|
+
return [self._format_one(v, fmt) for v in values]
|
|
74
|
+
|
|
75
|
+
def _format_one(self, value, fmt):
|
|
76
|
+
dt = self._to_datetime(value)
|
|
77
|
+
if dt is None:
|
|
78
|
+
return str(value)
|
|
79
|
+
return dt.strftime(fmt)
|
|
80
|
+
|
|
81
|
+
def __call__(self, value, pos=None):
|
|
82
|
+
return self._format_one(value, '%b %d')
|
|
83
|
+
|
|
84
|
+
def __repr__(self):
|
|
85
|
+
return 'ConciseDateFormatter()'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""rsplotlib._figure_defaults - 图形创建相关的默认值
|
|
2
|
+
|
|
3
|
+
集中管理 figure 尺寸、DPI 等默认值,避免散落在 pyplot 模块中。
|
|
4
|
+
底层实现: Rust figure 模块
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .. import rsplotlib as _rs
|
|
8
|
+
|
|
9
|
+
# 默认图形尺寸(英寸),与 matplotlib 默认一致
|
|
10
|
+
DEFAULT_FIGSIZE = _rs.get_default_figsize()
|
|
11
|
+
|
|
12
|
+
# 默认 DPI
|
|
13
|
+
DEFAULT_DPI = _rs.get_default_dpi()
|
rsplotlib/gridspec.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""rsplotlib.gridspec - Matplotlib GridSpec 兼容接口
|
|
2
|
+
|
|
3
|
+
提供子图网格布局管理。
|
|
4
|
+
底层实现已迁移至 Rust 层,此模块为保持完整 Python 接口的薄包装层。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .. import rsplotlib as _rs
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GridSpec:
|
|
11
|
+
"""GridSpec 布局管理器
|
|
12
|
+
|
|
13
|
+
用于在 Figure 中创建子图网格布局。
|
|
14
|
+
底层实现: Rust GridSpec
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
nrows: 行数
|
|
18
|
+
ncols: 列数
|
|
19
|
+
left: 左边界 (0-1)
|
|
20
|
+
bottom: 下边界 (0-1)
|
|
21
|
+
right: 右边界 (0-1)
|
|
22
|
+
top: 上边界 (0-1)
|
|
23
|
+
wspace: 列间距
|
|
24
|
+
hspace: 行间距
|
|
25
|
+
width_ratios: 列宽比例
|
|
26
|
+
height_ratios: 行高比例
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, nrows=1, ncols=1, left=None, bottom=None, right=None,
|
|
30
|
+
top=None, wspace=None, hspace=None, width_ratios=None,
|
|
31
|
+
height_ratios=None):
|
|
32
|
+
self.nrows = nrows
|
|
33
|
+
self.ncols = ncols
|
|
34
|
+
self.left = left
|
|
35
|
+
self.bottom = bottom
|
|
36
|
+
self.right = right
|
|
37
|
+
self.top = top
|
|
38
|
+
self.wspace = wspace
|
|
39
|
+
self.hspace = hspace
|
|
40
|
+
self.width_ratios = width_ratios or [1] * ncols
|
|
41
|
+
self.height_ratios = height_ratios or [1] * nrows
|
|
42
|
+
self._impl = _rs.GridSpec(nrows, ncols, left, bottom, right, top, wspace, hspace, width_ratios, height_ratios)
|
|
43
|
+
|
|
44
|
+
def __getitem__(self, key):
|
|
45
|
+
"""支持 gs[row, col] 和 gs[row_start:row_end, col_start:col_end] 语法
|
|
46
|
+
|
|
47
|
+
底层实现: Rust GridSpec.__getitem__
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
SubplotSpec: 子图定位器
|
|
51
|
+
"""
|
|
52
|
+
result = self._impl.__getitem__(key)
|
|
53
|
+
# 将 Rust SubplotSpec 包装为 Python SubplotSpec
|
|
54
|
+
return SubplotSpec._from_rust(result)
|
|
55
|
+
|
|
56
|
+
def get_subplot_params(self, figure=None):
|
|
57
|
+
"""获取子图布局参数"""
|
|
58
|
+
return {
|
|
59
|
+
'left': self.left,
|
|
60
|
+
'bottom': self.bottom,
|
|
61
|
+
'right': self.right,
|
|
62
|
+
'top': self.top,
|
|
63
|
+
'wspace': self.wspace,
|
|
64
|
+
'hspace': self.hspace,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
def tight_layout(self, figure=None, renderer=None, pad=1.08, h_pad=None, w_pad=None, rect=None):
|
|
68
|
+
"""自动调整布局"""
|
|
69
|
+
self._impl.tight_layout(figure, renderer)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class SubplotSpec:
|
|
73
|
+
"""子图定位器
|
|
74
|
+
|
|
75
|
+
底层实现: Rust SubplotSpec
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def __init__(self, gridspec, row_start=0, row_end=1, col_start=0, col_end=1):
|
|
79
|
+
self.gridspec = gridspec
|
|
80
|
+
self.row_start = row_start
|
|
81
|
+
self.row_end = row_end
|
|
82
|
+
self.col_start = col_start
|
|
83
|
+
self.col_end = col_end
|
|
84
|
+
if gridspec is not None:
|
|
85
|
+
self.numRows = gridspec.nrows
|
|
86
|
+
self.numCols = gridspec.ncols
|
|
87
|
+
else:
|
|
88
|
+
self.numRows = max(row_end, 1)
|
|
89
|
+
self.numCols = max(col_end, 1)
|
|
90
|
+
self.rowStart = row_start
|
|
91
|
+
self.rowStop = row_end
|
|
92
|
+
self.colStart = col_start
|
|
93
|
+
self.colStop = col_end
|
|
94
|
+
# 创建 Rust 实现
|
|
95
|
+
if gridspec is not None:
|
|
96
|
+
self._impl = _rs.SubplotSpec(gridspec._impl, row_start, row_end, col_start, col_end)
|
|
97
|
+
else:
|
|
98
|
+
self._impl = _rs.SubplotSpec(None, row_start, row_end, col_start, col_end)
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def _from_rust(cls, rust_spec):
|
|
102
|
+
"""从 Rust SubplotSpec 创建 Python 包装"""
|
|
103
|
+
instance = cls.__new__(cls)
|
|
104
|
+
instance._impl = rust_spec
|
|
105
|
+
instance.numRows = rust_spec.numRows
|
|
106
|
+
instance.numCols = rust_spec.numCols
|
|
107
|
+
instance.rowStart = rust_spec.rowStart
|
|
108
|
+
instance.rowStop = rust_spec.rowStop
|
|
109
|
+
instance.colStart = rust_spec.colStart
|
|
110
|
+
instance.colStop = rust_spec.colStop
|
|
111
|
+
instance.row_start = rust_spec.rowStart
|
|
112
|
+
instance.row_end = rust_spec.rowStop
|
|
113
|
+
instance.col_start = rust_spec.colStart
|
|
114
|
+
instance.col_end = rust_spec.colStop
|
|
115
|
+
instance.gridspec = None # 简化处理
|
|
116
|
+
return instance
|
|
117
|
+
|
|
118
|
+
def get_position(self, figure):
|
|
119
|
+
"""返回子图位置 (left, bottom, width, height)
|
|
120
|
+
|
|
121
|
+
底层实现: Rust SubplotSpec.get_position
|
|
122
|
+
"""
|
|
123
|
+
return self._impl.get_position(figure)
|
|
124
|
+
|
|
125
|
+
def get_grid_span(self):
|
|
126
|
+
"""返回网格跨度"""
|
|
127
|
+
return (self.rowStart, self.rowStop, self.colStart, self.colStop)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# 便利函数
|
|
131
|
+
def GridSpecFromSubplotSpec(nrows, ncols, subplot_spec, **kwargs):
|
|
132
|
+
"""从 SubplotSpec 创建 GridSpec"""
|
|
133
|
+
from ..rsplotlib import gridspec_from_subplotspec
|
|
134
|
+
# 参数提取
|
|
135
|
+
left = kwargs.get('left')
|
|
136
|
+
bottom = kwargs.get('bottom')
|
|
137
|
+
right = kwargs.get('right')
|
|
138
|
+
top = kwargs.get('top')
|
|
139
|
+
wspace = kwargs.get('wspace')
|
|
140
|
+
hspace = kwargs.get('hspace')
|
|
141
|
+
width_ratios = kwargs.get('width_ratios')
|
|
142
|
+
height_ratios = kwargs.get('height_ratios')
|
|
143
|
+
rust_gs = gridspec_from_subplotspec(
|
|
144
|
+
nrows, ncols, left=left, bottom=bottom, right=right, top=top,
|
|
145
|
+
wspace=wspace, hspace=hspace, width_ratios=width_ratios,
|
|
146
|
+
height_ratios=height_ratios,
|
|
147
|
+
)
|
|
148
|
+
# 包装为 Python GridSpec
|
|
149
|
+
gs = GridSpec.__new__(GridSpec)
|
|
150
|
+
gs.nrows = nrows
|
|
151
|
+
gs.ncols = ncols
|
|
152
|
+
gs.left = left
|
|
153
|
+
gs.bottom = bottom
|
|
154
|
+
gs.right = right
|
|
155
|
+
gs.top = top
|
|
156
|
+
gs.wspace = wspace
|
|
157
|
+
gs.hspace = hspace
|
|
158
|
+
gs.width_ratios = width_ratios or [1] * ncols
|
|
159
|
+
gs.height_ratios = height_ratios or [1] * nrows
|
|
160
|
+
gs._impl = rust_gs
|
|
161
|
+
return gs
|
rsplotlib/patches.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class FancyArrowPatch:
|
|
2
|
+
def __init__(self, posA, posB, arrowstyle=None, connectionstyle=None,
|
|
3
|
+
color=None, linestyle=None, linewidth=None, mutation_scale=None,
|
|
4
|
+
shrinkA=None, shrinkB=None, zorder=None):
|
|
5
|
+
self.posA = posA
|
|
6
|
+
self.posB = posB
|
|
7
|
+
self.arrowstyle = arrowstyle
|
|
8
|
+
self.connectionstyle = connectionstyle
|
|
9
|
+
self.color = color
|
|
10
|
+
self.linestyle = linestyle
|
|
11
|
+
self.linewidth = linewidth
|
|
12
|
+
self.mutation_scale = mutation_scale
|
|
13
|
+
self.shrinkA = shrinkA if shrinkA is not None else 0.0
|
|
14
|
+
self.shrinkB = shrinkB if shrinkB is not None else 0.0
|
|
15
|
+
self.zorder = zorder
|
|
16
|
+
self._dpi_cor = 1.0
|
|
17
|
+
self._posA_posB = (posA, posB)
|
|
18
|
+
self.patchA = None
|
|
19
|
+
self.patchB = None
|
|
20
|
+
|
|
21
|
+
def _convert_xy_units(self, xy):
|
|
22
|
+
return xy
|
|
23
|
+
|
|
24
|
+
def get_connectionstyle(self):
|
|
25
|
+
return self.connectionstyle
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class _Path:
|
|
29
|
+
def __init__(self, vertices, codes=None):
|
|
30
|
+
self.vertices = vertices
|
|
31
|
+
self.codes = codes
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class _ConnectionStyleType:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ConnectionStyle(_ConnectionStyleType):
|
|
39
|
+
def __init__(self, style):
|
|
40
|
+
self.style = style
|
|
41
|
+
|
|
42
|
+
def __call__(self, posA, posB, *args, **kwargs):
|
|
43
|
+
x1, y1 = posA
|
|
44
|
+
x2, y2 = posB
|
|
45
|
+
cx = (x1 + x2) / 2
|
|
46
|
+
cy = (y1 + y2) / 2
|
|
47
|
+
return _Path([posA, (cx, cy), posB], [1, 2, 2])
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
ConnectionStyle.Angle3 = _ConnectionStyleType
|
|
51
|
+
ConnectionStyle.Arc3 = _ConnectionStyleType
|
|
52
|
+
ConnectionStyle.Angle = _ConnectionStyleType
|
|
53
|
+
ConnectionStyle.Arc = _ConnectionStyleType
|
|
54
|
+
ConnectionStyle.Bar = _ConnectionStyleType
|
rsplotlib/path.py
ADDED
rsplotlib/pylab.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""rsplotlib.pylab - Matplotlib pylab 兼容接口"""
|
|
2
|
+
|
|
3
|
+
from .utils._rcparams import rcParams, rcParamsOrig
|
|
4
|
+
|
|
5
|
+
# mpl 模块可以从 pylab 导入
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MplModule:
|
|
9
|
+
"""兼容 matplotlib 的 mpl 模块"""
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.rcParams = rcParams
|
|
13
|
+
self.rcParamsOrig = rcParamsOrig
|
|
14
|
+
|
|
15
|
+
def get_backend(self):
|
|
16
|
+
return 'Agg'
|
|
17
|
+
|
|
18
|
+
def set_backend(self, backend):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
mpl = MplModule()
|