Python Pandas DataFrame 直接绘制雷达图
在数据分析与报表呈现中,雷达图(Radar Chart,又称蜘蛛网图)常用于评估个人综合能力、车型配置对比或算法多维度指标评分。虽然 Pandas 官方的 DataFrame.plot() 原生 API 并没有内置 kind='radar' 这一快捷参数,但借助底层 Matplotlib 的极坐标投影(Polar Projection),我们完全可以直接以整张 DataFrame 作为数据源,仅用数行代码批量遍历并绘制出规整、专业的多维度雷达图。
一、为什么 Pandas 不能直接 df.plot(kind='radar')?
Pandas 的 DataFrame.plot() 主要针对笛卡尔直角坐标系设计,内置了折线图、柱状图、散点图、直方图等常见图表。而雷达图本质上是极坐标系(Polar Coordinates)下的闭合多边形折线图。极坐标由极角(角度 $\theta$)和极径(数值半径 $r$)决定,要求每个维度按角度均分,并且为了形成封闭的几何面,最后一个维度必须重新连接回起点。
因此,所谓“直接绘制雷达图”,核心解决路径是:保持 DataFrame 的结构不变(每一行代表一个实体,每一列代表一个指标),通过算法自动计算各个维度的等分角度,将行数据首尾复制闭合后直接投射至极坐标系中。
二、标准实现:四步完成 DataFrame 雷达图绘制
直接利用 Python 的 pandas、numpy 和 matplotlib.pyplot,我们遵循清晰的四步流程完成绘图:
完整代码示例
假设我们有一份包含三款智能手机在五个维度(屏幕、续航、拍照、性能、做工)评分的 DataFrame,以下是标准完整的可执行代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 1. 准备 DataFrame 数据
data = {
"机型": ["Flagship A", "Performance B", "Battery King C"],
"屏幕素质": [92, 80, 75],
"续航能力": [70, 75, 98],
"拍照表现": [95, 78, 70],
"核心性能": [88, 96, 82],
"机身做工": [90, 84, 80]
}
df = pd.DataFrame(data).set_index("机型")
# 2. 提取维度特征与计算角度
categories = list(df.columns)
num_vars = len(categories)
# 计算每个轴的角度(2*pi 等分)
angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist()
# 关键:闭合雷达图(将首个维度追加到末尾)
angles += angles[:1]
# 3. 创建极坐标画布
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
# 调整极坐标起始角度(让第一个轴位于正上方,按顺时针旋转)
ax.set_theta_offset(np.pi / 2)
ax.set_theta_direction(-1)
# 设置极轴标签(X 轴刻度对应维度名称)
plt.xticks(angles[:-1], categories, fontproperties="PingFang SC", size=10)
# 设置径向网格刻度范围(例如 0 - 100)
ax.set_rlabel_position(0)
plt.yticks([20, 40, 60, 80, 100], ["20", "40", "60", "80", "100"], color="grey", size=8)
plt.ylim(0, 100)
# 4. 遍历 DataFrame 每一行,直接绘制多边形和填充面
colors = ["#6B88A6", "#71A397", "#E58E26"]
for i, (index_label, row) in enumerate(df.iterrows()):
values = row.values.flatten().tolist()
values += values[:1] # 闭合数据
# 绘制外边框线条
ax.plot(angles, values, linewidth=2, linestyle='solid', label=index_label, color=colors[i % len(colors)])
# 填充半透明区域
ax.fill(angles, values, color=colors[i % len(colors)], alpha=0.25)
# 添加图例
plt.legend(loc="upper right", bbox_to_anchor=(0.1, 0.1))
plt.title("智能机型多维度综合评测雷达图", y=1.08, fontproperties="PingFang SC", size=14, weight="bold")
plt.tight_layout()
plt.show()
三、进阶封装:一行代码直接绘制(df.pipe 或自定义函数)
为了让调用体验达到像 df.plot() 一样自然,我们可以利用 Pandas 的管道机制 df.pipe() 或者直接封装一个通用函数 plot_radar(df)。这样无需每次手动计算三角函数和闭合数据,只需传入 DataFrame 即可一行出图。
封装可重用的直绘函数
def plot_radar_df(df, r_max=100, fill_alpha=0.2, title=None):
"""
直接从 DataFrame 绘制多维雷达图通用函数
:param df: 行索引为分类名称,列名为维度的 DataFrame
:param r_max: 雷达图外圈最大值
:param fill_alpha: 面积填充透明度
:param title: 图表标题
"""
categories = list(df.columns)
N = len(categories)
angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
angles += angles[:1]
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
ax.set_theta_offset(np.pi / 2)
ax.set_theta_direction(-1)
plt.xticks(angles[:-1], categories)
ax.set_ylim(0, r_max)
for idx, row in df.iterrows():
vals = row.tolist()
vals += vals[:1]
ax.plot(angles, vals, label=str(idx), linewidth=1.8)
ax.fill(angles, vals, alpha=fill_alpha)
plt.legend(loc="upper right", bbox_to_anchor=(1.25, 1.1))
if title:
plt.title(title, y=1.08)
return fig, ax
# 使用方式:直接传入任意符合格式的 DataFrame
plot_radar_df(df, r_max=100, title="产品综合指标直绘雷达图")
plt.show()
四、绘制雷达图的 4 个关键注意事项
虽然将 DataFrame 转换为雷达图的代码并不长,但在实际业务数据处理中,以下细节经常导致图形显示异常或传达错误的信息:
Pandas DataFrame 虽然没有直接提供 df.plot(kind='radar'),但由于 DataFrame 的行、列天然对应实体与维度,只需通过“提取列名 → 计算均分角 → 追加首项闭合 → 遍历行绘制极坐标”四步,即可实现从 DataFrame 数据到专业雷达图的直接映射与批量呈现。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









