xlin 0.1.34__tar.gz → 0.1.36__tar.gz
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.
- {xlin-0.1.34 → xlin-0.1.36}/PKG-INFO +1 -1
- {xlin-0.1.34 → xlin-0.1.36}/pyproject.toml +1 -1
- {xlin-0.1.34 → xlin-0.1.36}/xlin/statistic.py +125 -4
- {xlin-0.1.34 → xlin-0.1.36}/LICENSE +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/README.md +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/__init__.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/ischinese.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/jsonl.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/metric.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/multiprocess_mapping.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/read_as_dataframe.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/timing.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/util.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/xls2xlsx.py +0 -0
- {xlin-0.1.34 → xlin-0.1.36}/xlin/yaml.py +0 -0
@@ -1,3 +1,4 @@
|
|
1
|
+
import sys
|
1
2
|
from typing import List, Optional
|
2
3
|
from collections import defaultdict
|
3
4
|
|
@@ -108,12 +109,119 @@ Kurtosis: {float((data - mean).mean()**4 / std**4):.4f}\
|
|
108
109
|
|
109
110
|
# 显示图形
|
110
111
|
plt.tight_layout()
|
111
|
-
plt.show()
|
112
112
|
if fig_save_path is not None:
|
113
113
|
plt.savefig(fig_save_path, dpi=300)
|
114
|
+
plt.show()
|
114
115
|
|
116
|
+
def draw_radar(categories: list[str],
|
117
|
+
data: dict[str, list[float]],
|
118
|
+
ranges=(0, 5),
|
119
|
+
title: str = "Radar Chart",
|
120
|
+
size: tuple[float, float] = (6, 6),
|
121
|
+
colors: list[str] = None,
|
122
|
+
annotation_offset: float = 0.03,
|
123
|
+
annotation_kwargs: dict = None,
|
124
|
+
chinese_font: bool = False,
|
125
|
+
font_name: str = 'Heiti TC',
|
126
|
+
font_path: str = None,
|
127
|
+
fig_save_path: str = None):
|
128
|
+
import numpy as np
|
129
|
+
import matplotlib.pyplot as plt
|
130
|
+
from matplotlib.font_manager import FontProperties
|
131
|
+
"""
|
132
|
+
Draw a radar chart with optional Chinese font support and configurable annotations.
|
133
|
+
|
134
|
+
Parameters:
|
135
|
+
- categories: list of dimension names.
|
136
|
+
- data: dict mapping series name -> list of values (same length as categories).
|
137
|
+
- ranges: tuple (min, max) for radial axis.
|
138
|
+
- title: chart title.
|
139
|
+
- size: figure size tuple.
|
140
|
+
- colors: list of color hex strings.
|
141
|
+
- annotation_offset: fraction of (max-min) to offset text.
|
142
|
+
- annotation_kwargs: additional kwargs for plt.text (font size, bbox, etc).
|
143
|
+
- chinese_font: whether to enable Chinese font support.
|
144
|
+
- font_name: name of a system font to use (overrides defaults).
|
145
|
+
- font_path: path to a .ttf font file (used if provided).
|
146
|
+
- fig_save_path: if set, saves figure to this path (PNG at 300dpi).
|
147
|
+
"""
|
148
|
+
# Validate data
|
149
|
+
N = len(categories)
|
150
|
+
for label, values in data.items():
|
151
|
+
if len(values) != N:
|
152
|
+
raise ValueError(f"Values for '{label}' must have length {N}")
|
153
|
+
|
154
|
+
# Font configuration
|
155
|
+
if font_path:
|
156
|
+
prop = FontProperties(fname=font_path)
|
157
|
+
plt.rcParams['font.family'] = prop.get_name()
|
158
|
+
elif font_name:
|
159
|
+
plt.rcParams['font.family'] = font_name
|
160
|
+
elif chinese_font:
|
161
|
+
if sys.platform == "darwin":
|
162
|
+
plt.rcParams['font.family'] = ['Heiti TC', 'Arial Unicode MS']
|
163
|
+
elif sys.platform.startswith("win"):
|
164
|
+
plt.rcParams['font.family'] = ['SimHei', 'Microsoft YaHei']
|
165
|
+
else:
|
166
|
+
# Fallback to Arial Unicode
|
167
|
+
plt.rcParams['font.family'] = ['Arial Unicode MS']
|
168
|
+
else:
|
169
|
+
plt.rcParams['font.family'] = ['Arial']
|
170
|
+
|
171
|
+
plt.rcParams['axes.unicode_minus'] = False
|
172
|
+
|
173
|
+
# Prepare angles
|
174
|
+
angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
|
175
|
+
angles += angles[:1]
|
176
|
+
|
177
|
+
# Colors
|
178
|
+
default_colors = ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f"]
|
179
|
+
colors = colors or default_colors
|
180
|
+
|
181
|
+
max_value = max(max(values) for values in data.values())
|
182
|
+
min_value = min(min(values) for values in data.values())
|
183
|
+
if ranges[0] > min_value or ranges[1] < max_value:
|
184
|
+
ranges = (min_value, max_value + 1)
|
185
|
+
|
186
|
+
# Create plot
|
187
|
+
fig, ax = plt.subplots(figsize=size, subplot_kw=dict(polar=True))
|
188
|
+
ax.set_theta_offset(np.pi / 2)
|
189
|
+
ax.set_theta_direction(-1)
|
190
|
+
ax.set_xticks(angles[:-1])
|
191
|
+
ax.set_xticklabels(categories, fontsize=12)
|
192
|
+
ax.set_ylim(ranges)
|
193
|
+
ax.set_rlabel_position(180 / N)
|
194
|
+
ax.grid(color='gray', linestyle='--', linewidth=0.5)
|
195
|
+
|
196
|
+
# Plot each series
|
197
|
+
for idx, (label, values) in enumerate(data.items()):
|
198
|
+
vals = values + values[:1]
|
199
|
+
color = colors[idx % len(colors)]
|
200
|
+
ax.plot(angles, vals, color=color, linewidth=2, label=label)
|
201
|
+
ax.fill(angles, vals, color=color, alpha=0.25)
|
202
|
+
|
203
|
+
# Annotate points
|
204
|
+
for angle, val in zip(angles, vals):
|
205
|
+
offset = (ranges[1] - ranges[0]) * annotation_offset
|
206
|
+
ha = 'left' if np.cos(angle) >= 0 else 'right'
|
207
|
+
va = 'bottom' if np.sin(angle) >= 0 else 'top'
|
208
|
+
txt_kwargs = dict(fontsize=10, ha=ha, va=va, bbox=dict(boxstyle="round,pad=0.3", edgecolor=color, facecolor='white', alpha=0.8))
|
209
|
+
if annotation_kwargs:
|
210
|
+
txt_kwargs.update(annotation_kwargs)
|
211
|
+
ax.text(angle, val + offset, f"{val}", **txt_kwargs)
|
212
|
+
|
213
|
+
ax.set_title(title, va='bottom', fontsize=16)
|
214
|
+
ax.legend(loc='upper right', bbox_to_anchor=(1.15, 1.05))
|
215
|
+
plt.tight_layout()
|
115
216
|
|
116
|
-
|
217
|
+
if fig_save_path:
|
218
|
+
plt.savefig(fig_save_path, dpi=300, bbox_inches='tight')
|
219
|
+
plt.show()
|
220
|
+
|
221
|
+
|
222
|
+
def draw_preds_labels(preds: list[str], labels: list[str],
|
223
|
+
title="Pred and Label Class Distribution",
|
224
|
+
fig_save_path: Optional[str]=None):
|
117
225
|
from collections import Counter
|
118
226
|
import matplotlib.pyplot as plt
|
119
227
|
|
@@ -159,9 +267,9 @@ def draw_preds_labels(preds: list[str], labels: list[str], title="Pred and Label
|
|
159
267
|
plt.suptitle(title)
|
160
268
|
|
161
269
|
plt.tight_layout()
|
162
|
-
plt.show()
|
163
270
|
if fig_save_path is not None:
|
164
271
|
plt.savefig(fig_save_path, dpi=300)
|
272
|
+
plt.show()
|
165
273
|
|
166
274
|
|
167
275
|
def generate_classification_report(predictions: List[str], labels: List[str]) -> dict:
|
@@ -328,4 +436,17 @@ if __name__ == "__main__":
|
|
328
436
|
preds = ["cat", "dog", "cat", "dog", "extra1", "extra2"]
|
329
437
|
truth = ["cat", "cat", "dog", "dog", "dog", "dog"]
|
330
438
|
|
331
|
-
print_classification_report(preds, truth)
|
439
|
+
print_classification_report(preds, truth)
|
440
|
+
draw_preds_labels(preds, truth, title="Pred and Label Class Distribution", fig_save_path="assets/pred_label_distribution.png")
|
441
|
+
|
442
|
+
import random
|
443
|
+
|
444
|
+
lengths = [random.randint(0, 100) for _ in range(100)]
|
445
|
+
draw_histogram(lengths, bins=50, title="Length Distribution", fig_save_path="assets/length_distribution.png")
|
446
|
+
|
447
|
+
categories = ['速度', '可靠性', '舒适度', '安全性', '效率', '风格', '性价比']
|
448
|
+
data = {
|
449
|
+
'产品 A': [4, 3, 2, 5, 4, 3, -1],
|
450
|
+
'产品 B': [3, 4, 5, 3, 3, 4, 8]
|
451
|
+
}
|
452
|
+
draw_radar(categories, data, title="产品对比雷达图", chinese_font=True, fig_save_path="assets/radar_chart.png")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|