ggpx_statistics/radarref.py

119 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)