ggpx_statistics/radarref.py

119 lines
3.7 KiB
Python
Raw Permalink Normal View History

2024-11-16 11:19:03 +08:00
from io import BytesIO
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
class Radar(object):
def __init__(self, figure, title, labels, epoch, rect=None):
if rect is None:
rect = [0.1, 0.05, 0.75, 0.9]
self.n = len(title)
self.angles = np.arange(0, 360, 360.0 / self.n)
self.labels = labels
self.axes = [figure.add_axes(rect, projection='polar', label='axes%d' % i) for i in range(self.n)]
self.ax = self.axes[0]
self.ax.set_thetagrids(self.angles, labels=title, fontsize=12)
self.ax.xaxis.set_tick_params(pad=22) # Increase padding to move labels outward
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid(False)
ax.xaxis.set_visible(False)
for ax, angle, label, i in zip(self.axes, self.angles, labels, epoch):
ax.set_rgrids(i[1:], angle=angle, labels=label)
ax.spines['polar'].set_visible(False)
ax.set_ylim(i[0], i[-1])
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
# 第一个值保持不变
adjusted_values = [values[0]]
# 获取 labels 对应的最后一位的差值
base_last_value = float(self.labels[0][-1]) # 第一个 labels 列表的最后一位
# 计算新的 values
for i in range(1, len(values)):
current_label_last_value = float(self.labels[i][-1]) # 当前 labels 列表的最后一位
difference = current_label_last_value - base_last_value
adjusted_value = values[i] - difference
adjusted_values.append(adjusted_value)
# 将第一个值追加到最后,闭合图形
adjusted_values.append(adjusted_values[0])
# 绘制雷达图
self.ax.plot(angle, adjusted_values, *args, **kw)
def generate_lab(max_values, length=5, step=1):
"""
根据最大值向量生成lab标签列表
"""
lab = []
for max_val in max_values:
labels = [str(round(val, 2)) for val in np.arange(max_val - (length - 1) * step, max_val + step, step)]
lab.append(labels)
return lab
def generate_epo(max_values, length=6, step=1):
"""
根据最大值向量生成epo刻度范围列表
"""
epo = []
for max_val in max_values:
range_values = [round(val, 2) for val in np.arange(max_val - (length - 1) * step, max_val + step, step)]
epo.append(range_values)
return epo
def plot_radar(data, max_values):
"""
绘制雷达图根据数据和最大值生成图表
"""
fig = plt.figure(figsize=(10, 8))
tit = data.columns.tolist()
lab = generate_lab(max_values, length=5, step=1)
epo = generate_epo(max_values, length=6, step=1)
plt.rcParams['font.sans-serif'] = ['SimHei']
radar = Radar(fig, tit, lab, epo)
# 遍历 DataFrame 的每一行
colors = plt.colormaps.get_cmap('tab20')
for i, (idx, row) in enumerate(data.iterrows()):
radar.plot(row.values.tolist(), '-', lw=2, color=colors(i), alpha=0.4, label=idx)
radar.ax.legend(bbox_to_anchor=(1.2, 1.05))
# plt.savefig('fig.png', dpi=300)
# 将图像保存到字节流中
img_bytes = BytesIO()
plt.savefig(img_bytes, format='png')
# 设置字节流的位置到开始
img_bytes.seek(0)
# plt.show()
plt.close()
return img_bytes
if __name__ == '__main__':
# 一个行名为样本名列名为指标名的pd.dataframe
data = pd.read_csv('./radartest.csv', index_col=0)
# 任务设置的每个指标的最大值
max_values = [10, 15, 15, 10, 15, 5, 10, 10, 5, 5] # 示例最大值向量
# 使用这个函数
plot_radar(data, max_values)