【python】matplotlib(radar chart)

在这里插入图片描述

1、功能描述和原理介绍

基于 matplotlib 实现雷达图的绘制

一、雷达图的基本概念

雷达图(Radar Chart),也被称为蛛网图或星型图,是一种用于可视化多个变量之间关系的图表形式。它常用于比较多个变量之间的关系,特别是在展示各个维度的综合表现时非常有用。雷达图的基本构造是一个圆形网格,代表数据的各个维度。每个维度对应一个顶点,这些顶点通过直线连接,形成一个封闭的多边形。

二、绘制原理

  • 极坐标系统:
    雷达图是基于极坐标系统绘制的。在极坐标系统中,点的位置由角度和半径两个参数决定。
    在雷达图中,每个维度对应一个特定的角度,这些角度通常是等间隔分布的。

  • 数据映射:
    在绘制雷达图之前,需要将数据映射到极坐标系统上。这通常涉及将每个维度的值转换为对应的半径长度。
    为了保证各个维度之间的数值比例能够做同级别的比较,通常需要对数据进行标准化处理。

  • 绘制多边形:
    绘制雷达图时,从中心点开始,按照每个维度的角度绘制射线,并在射线上根据数据的值确定数据点的位置。
    将这些数据点依次连接起来,形成一个封闭的多边形,这个多边形就是雷达图的基本形状。

  • 区域填充:
    为了增强雷达图的视觉效果,通常会对多边形内部进行填充。
    填充的颜色、透明度等属性可以根据需要进行调整。

三、matplotlib绘制雷达图的步骤

  • 准备数据:
    确定要展示的维度和数据集。
    对数据进行标准化处理(如果需要)。

  • 设置图形大小和子图:
    使用 plt.figure() 设置图形的整体大小。
    使用 plt.subplots() 或 fig.add_subplot() 创建极坐标子图。

  • 绘制雷达图:
    使用 ax.plot() 或 ax.fill_between() 等方法绘制雷达图。
    设置角度和半径参数,确保数据正确映射到极坐标系统上。

  • 设置标签和标题:
    使用 ax.set_xticks() 和 ax.set_xticklabels() 设置角度标签。
    使用 plt.title() 或 ax.set_title() 设置图形标题。

  • 显示图形:
    使用 plt.show() 显示绘制好的雷达图。

四、注意事项

  • 数据标准化:在绘制雷达图之前,通常需要对数据进行标准化处理,以保证各个维度之间的数值比例能够做同级别的比较。
  • 角度设置:角度的设置应确保每个维度都能均匀分布在雷达图上。
  • 图形美观:可以通过调整颜色、透明度、线型等属性来增强雷达图的视觉效果。

2、代码实现

原始数据

# 漫威英雄
abilities = ['智力', '力量', '速度', '耐力', '能量', '技能']
super_heros = {
    '美国队长': [5, 4, 3, 4, 3, 7],
    '钢铁侠': [6, 3, 5, 5, 3, 3],
    '绿巨人': [6, 7, 3, 7, 1, 5],
    '蜘蛛侠': [5, 4, 5, 4, 2, 5],
    '灭霸': [7, 7, 7, 7, 7, 7],
    '雷神': [2, 5, 6, 7, 6, 6],
    '绯红女巫': [3, 3, 3, 3, 7, 3],
    '黑寡妇': [5, 3, 2, 3, 3, 7],
    '鹰眼': [5, 3, 3, 2, 2, 7],
}

转化后的数据


list1 = list(super_heros.keys())
print(f"'group':{list1},")

for index, ability in enumerate(abilities):
    attrib = []
    for item in super_heros:
        attrib.append(super_heros[item][index])
    print(f"'{ability}':", attrib, end=",\n")

output

'group':['美国队长', '钢铁侠', '绿巨人', '蜘蛛侠', '灭霸', '雷神', '绯红女巫', '黑寡妇', '鹰眼'],
'智力': [5, 6, 6, 5, 7, 2, 3, 5, 5],
'力量': [4, 3, 7, 4, 7, 5, 3, 3, 3],
'速度': [3, 5, 3, 5, 7, 6, 3, 2, 3],
'耐力': [4, 5, 7, 4, 7, 7, 3, 3, 2],
'能量': [3, 3, 1, 2, 7, 6, 7, 3, 2],
'技能': [7, 3, 5, 5, 7, 6, 3, 7, 7],

下面基于处理后的数据绘制雷达图

首先导入必要的库函数

import matplotlib.pyplot as plt
import pandas as pd
from math import pi

配置好支持中文显示

from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

配置绘制的数据

# Set data
df = pd.DataFrame({
        'group':['美国队长', '钢铁侠', '绿巨人', '蜘蛛侠', '灭霸', '雷神', '绯红女巫', '黑寡妇', '鹰眼'],
        '智力': [5, 6, 6, 5, 7, 2, 3, 5, 5],
        '力量': [4, 3, 7, 4, 7, 5, 3, 3, 3],
        '速度': [3, 5, 3, 5, 7, 6, 3, 2, 3],
        '耐力': [4, 5, 7, 4, 7, 7, 3, 3, 2],
        '能量': [3, 3, 1, 2, 7, 6, 7, 3, 2],
        '技能': [7, 3, 5, 5, 7, 6, 3, 7, 7],
})

步骤1,创建背景

# ---------- 步骤1 创建背景
def make_spider(row, title, color):
    # number of variable
    # 变量类别
    categories = list(df)[1:]
    # 变量类别个数
    N = len(categories)

    # 设置每个点的角度值
    angles = [n / float(N) * 2 * pi for n in range(N)]
    angles += angles[:1]

    # Initialise the spider plot
    # 分图
    ax = plt.subplot(3, 3, row + 1, polar=True, )
    plt.subplots_adjust(wspace=0.3, hspace=0.5)

    # If you want the first axis to be on top:
    # 设置角度偏移
    ax.set_theta_offset(pi / 2)
    # 设置顺时针还是逆时针,1或者-1
    ax.set_theta_direction(-1)

    # Draw one axe per variable + add labels labels yet
    # 设置x轴的标签
    plt.xticks(angles[:-1], categories, color='grey', size=12)  # 最外围

    # Draw ylabels
    # 画标签
    ax.set_rlabel_position(0)
    plt.yticks([3, 6, 9], ["3", "6", "9"], color="grey", size=7)  # 内圈
    plt.ylim(0, 10)  # 英雄的各项数值介于 0-10 之间

    # Ind
    # 填充数据
    values = df.loc[row].drop('group').values.flatten().tolist()
    values += values[:1]
    ax.plot(angles, values, color=color, linewidth=2, linestyle='solid')
    ax.fill(angles, values, color=color, alpha=0.4)

    # Add a title
    # 设置标题
    plt.title(title, size=15, color=color, position=(0.5, 0.5))

代码解析

九个英雄,布局成 3x3 的形式 ax = plt.subplot(3, 3, row + 1, polar=True, )

可是适当扩大些行列间距,plt.subplots_adjust(wspace=0.3, hspace=0.5),防止图形绘制的时候重叠

绘制雷达图

my_dpi = 96
plt.figure(figsize=(1000 / my_dpi, 1000 / my_dpi), dpi=my_dpi)

# Create a color palette:
# 设定颜色
my_palette = plt.cm.get_cmap("gist_rainbow", len(df.index))

# Loop to plot
for row in range(0, len(df.index)):
    make_spider(row=row, title='hero ' + df['group'][row], color=my_palette(row))

plt.show()

plt.cm.get_cmap 颜色模式有许多种,可以自己选择

3、效果展示

在这里插入图片描述

试试更多的例子

在这里插入图片描述

4、完整代码

数据处理

# 漫威英雄
abilities = ['智力', '力量', '速度', '耐力', '能量', '技能']
super_heros = {
    '美国队长': [5, 4, 3, 4, 3, 7],
    '钢铁侠': [6, 3, 5, 5, 3, 3],
    '绿巨人': [6, 7, 3, 7, 1, 5],
    '蜘蛛侠': [5, 4, 5, 4, 2, 5],
    '灭霸': [7, 7, 7, 7, 7, 7],
    '雷神': [2, 5, 6, 7, 6, 6],
    '绯红女巫': [3, 3, 3, 3, 7, 3],
    '黑寡妇': [5, 3, 2, 3, 3, 7],
    '鹰眼': [5, 3, 3, 2, 2, 7],
}

# 火影忍者
abilities = ['忍', '体', '幻', '贤', '力', '速', '精', '印']
super_heros = {
    '旗木卡卡西': [10, 9, 8, 10, 7, 9, 6, 10],
    '自来也': [10, 9, 6, 9, 9, 9, 10, 9],
    '纲手': [10, 10, 7, 10, 10, 7, 8, 8],
    '宇智波鼬': [10, 9, 10, 10, 7, 10, 5, 10],
}

list1 = list(super_heros.keys())
print(f"'group':{list1},")

for index, ability in enumerate(abilities):
    attrib = []
    for item in super_heros:
        attrib.append(super_heros[item][index])
    print(f"'{ability}':", attrib, end=",\n")

雷达图绘制

import matplotlib.pyplot as plt
import pandas as pd
from math import pi

from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

# Set data
if 1:
    df = pd.DataFrame({
            'group':['美国队长', '钢铁侠', '绿巨人', '蜘蛛侠', '灭霸', '雷神', '绯红女巫', '黑寡妇', '鹰眼'],
            '智力': [5, 6, 6, 5, 7, 2, 3, 5, 5],
            '力量': [4, 3, 7, 4, 7, 5, 3, 3, 3],
            '速度': [3, 5, 3, 5, 7, 6, 3, 2, 3],
            '耐力': [4, 5, 7, 4, 7, 7, 3, 3, 2],
            '能量': [3, 3, 1, 2, 7, 6, 7, 3, 2],
            '技能': [7, 3, 5, 5, 7, 6, 3, 7, 7],
    })


if 0:
    df = pd.DataFrame({
        'group':['旗木卡卡西', '自来也', '纲手', '宇智波鼬'],
        '忍': [10, 10, 10, 10],
        '体': [9, 9, 10, 9],
        '幻': [8, 6, 7, 10],
        '贤': [10, 9, 10, 10],
        '力': [7, 9, 10, 7],
        '速': [9, 9, 7, 10],
        '精': [6, 10, 8, 5],
        '印': [10, 9, 8, 10],
    })

# ---------- 步骤1 创建背景
def make_spider(row, title, color):
    # number of variable
    # 变量类别
    categories = list(df)[1:]
    # 变量类别个数
    N = len(categories)

    # 设置每个点的角度值
    angles = [n / float(N) * 2 * pi for n in range(N)]
    angles += angles[:1]

    # Initialise the spider plot
    # 分图
    ax = plt.subplot(3, 3, row + 1, polar=True, )
    plt.subplots_adjust(wspace=0.3, hspace=0.5)

    # If you want the first axis to be on top:
    # 设置角度偏移
    ax.set_theta_offset(pi / 2)
    # 设置顺时针还是逆时针,1或者-1
    ax.set_theta_direction(-1)

    # Draw one axe per variable + add labels labels yet
    # 设置x轴的标签
    plt.xticks(angles[:-1], categories, color='grey', size=12)  # 最外围

    # Draw ylabels
    # 画标签
    ax.set_rlabel_position(0)
    plt.yticks([3, 6, 9], ["3", "6", "9"], color="grey", size=7)  # 内圈
    plt.ylim(0, 10)

    # Ind
    # 填充数据
    values = df.loc[row].drop('group').values.flatten().tolist()
    values += values[:1]
    ax.plot(angles, values, color=color, linewidth=2, linestyle='solid')
    ax.fill(angles, values, color=color, alpha=0.4)

    # Add a title
    # 设置标题
    plt.title(title, size=15, color=color, position=(0.5, 0.5))

# ---------- 步骤2 绘制图形
my_dpi = 96
plt.figure(figsize=(1000 / my_dpi, 1000 / my_dpi), dpi=my_dpi)

# Create a color palette:
# 设定颜色
my_palette = plt.cm.get_cmap("gist_rainbow", len(df.index))

# Loop to plot
for row in range(0, len(df.index)):
    make_spider(row=row, title=df['group'][row], color=my_palette(row))

plt.show()

5、多个雷达图绘制在一张图上

# Libraries
import matplotlib.pyplot as plt
import pandas as pd
from math import pi

from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

# Set data
df = pd.DataFrame({
    'group': ['旗木卡卡西', '自来也', '纲手', '宇智波鼬'],
    '忍': [10, 10, 10, 10],
    '体': [9, 9, 10, 9],
    '幻': [8, 6, 7, 10],
    '贤': [10, 9, 10, 10],
    '力': [7, 9, 10, 7],
    '速': [9, 9, 7, 10],
    '精': [6, 10, 8, 5],
    '印': [10, 9, 8, 10],
})

# ---------- 步骤1 创建背景

# number of variable
# 变量类别
categories = list(df)[1:]
# 变量类别个数
N = len(categories)

# 设置每个点的角度值
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]

# Initialise the spider plot
# 初始化极坐标网格
ax = plt.subplot(111, polar=True)

# If you want the first axis to be on top:
# 设置角度偏移
ax.set_theta_offset(pi / 2)
# 设置顺时针还是逆时针,1或者-1
ax.set_theta_direction(-1)

# Draw one axe per variable + add labels labels yet
# 设置x轴的标签
plt.xticks(angles[:-1], categories)

# Draw ylabels
# 画标签
ax.set_rlabel_position(0)
plt.yticks([3, 6, 9], ["3", "6", "9"], color="grey", size=7)
plt.ylim(0, 10)

# ---------- 步骤1 绘制数据

# 单独绘制每一组数据
my_palette = plt.cm.get_cmap("rainbow", len(df.index))  # 颜色
for index in range(len(df["group"])):
    values = df.loc[index].drop('group').values.flatten().tolist()
    values += values[:1]
    ax.plot(angles, values, color=my_palette(index),
            linewidth=1, linestyle='solid', label=df["group"][index])
    ax.fill(angles, values, color=my_palette(index), alpha=0.2)

# Add legend
# 添加图例
plt.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))
plt.show()

在这里插入图片描述

my_palette = plt.cm.get_cmap("rainbow", len(df.index)) # 颜色 可以自由搭配颜色模式

6、参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值