Python学习笔记·第27天:Matplotlib高级——雷达图、三维图与图例样式详解

一、绘制雷达图

业务场景:把学生的各科成绩画成雷达图,让用人单位一眼看出综合能力。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 课程名和对应成绩
courses = ['C++', 'Python', '高数', '大学英语', '软件工程', '组成原理', '数字图像处理', '计算机图形学']
scores = [80, 95, 78, 85, 45, 65, 80, 60]

dataLength = len(scores)  # 数据长度=8,因为有8门课

# 把圆周(2π)等分成8份,每份对应一门课
angles = np.linspace(0,              # 起始角度:0度
                     2*np.pi,        # 结束角度:360度(一圈)
                     dataLength,     # 分成8份
                     endpoint=False) # 不包含终点,否则0和360重复

np.linspace(0, 2*np.pi, 8, endpoint=False) 是什么意思?

参数 含义 大白话
0 起始值 从0度开始
2*np.pi 结束值 到360度结束
8 生成几个数 把360度切成8份
endpoint=False 不包含终点 8个角度:0°, 45°, 90°, 135°, 180°, 225°, 270°, 315°
python 复制代码
# 雷达图要闭合,首尾相连。把第一个成绩加到列表末尾
scores.append(scores[0])           # 成绩列表:最后补上80

# 角度也要闭合,把第一个角度加到数组末尾
angles = np.append(angles, angles[0])  # 角度数组:最后补上0°

为什么要首尾闭合? 雷达图是一个闭合的多边形,最后一个点要和第一个点连起来。所以成绩和角度都要在末尾补上第一个值。

python 复制代码
# 画雷达图
plt.polar(angles,       # 设置角度
          scores,       # 设置各角度上的数据
          'rv--',       # r=红色, v=三角形标记, --=虚线
          linewidth=2)  # 线条粗细为2

# 设置角度标签(把角度数值替换成课程名)
plt.thetagrids(angles*180/np.pi,  # 把弧度转成角度(0-360)
               courses,            # 显示为课程名
               fontproperties='simhei')  # 中文字体

# 填充雷达图内部
plt.fill(angles,          # 填充区域的角度
         scores,          # 填充区域的数据
         facecolor='r',   # 填充颜色=红色
         alpha=0.3)       # 透明度=0.3(0全透明,1不透明)

plt.show()  # 显示图形

angles*180/np.pi 是什么意思? NumPy用的是弧度制(一圈=2π),但显示需要角度制(一圈=360°)。180/np.pi 就是把弧度转成角度的换算系数。

二、绘制三维图形

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D  # 导入三维绘图工具

# 创建画布,声明绘制三维图形
fig = plt.figure()                      # 创建画布
ax = fig.gca(projection='3d')           # 设置为三维坐标系

# 生成螺旋线的数据
theta = np.linspace(-4*np.pi, 4*np.pi, 100)  # 角度:-4π到4π,生成100个点
z = np.linspace(-4, 4, 100)*0.3               # z轴:-4到4,乘以0.3缩小范围
r = z**4 + 1                                    # 半径:z的四次方加1
x = r * np.sin(theta)                           # x坐标 = 半径 × sin(角度)
y = r * np.cos(theta)                           # y坐标 = 半径 × cos(角度)

# 画三维曲线
ax.plot(x, y, z, 'rv-', label='参数曲线')  # r=红色, v=三角形, -=实线

plt.legend()  # 显示图例
plt.show()    # 显示图形

三、绘制三维曲面

python 复制代码
# 生成网格数据
x, y = np.mgrid[-2:2:20j, -2:2:20j]  # x和y各生成20个点,范围-2到2
z = 50 * np.sin(x + y*2)              # z的值由x和y通过公式计算

ax = plt.subplot(111, projection='3d')  # 创建三维子图

# 画三维曲面
ax.plot_surface(x, y, z,
                rstride=3,               # 行方向每隔3个点采样
                cstride=2,               # 列方向每隔2个点采样
                cmap=plt.cm.coolwarm)    # 颜色映射=冷暖色调

ax.set_xlabel('X')                                     # X轴标签
ax.set_ylabel('Y')                                     # Y轴标签
ax.set_zlabel('Z')                                     # Z轴标签
ax.set_title('三维面', fontproperties='simhei', fontsize=24)  # 标题

plt.show()

np.mgrid[-2:2:20j, -2:2:20j] 是什么意思? -2:2:20j 表示从-2到2生成20个等间距的点。mgrid 同时生成x和y两个方向的网格点,相当于在平面上铺了一张20×20的点阵。

四、绘图区域切分

python 复制代码
ax1 = plt.subplot(241)                    # 2行4列,第1个位置
ax2 = plt.subplot(242, projection='polar') # 第2个,极坐标图
ax3 = plt.subplot(243, projection='polar') # 第3个,极坐标图
ax4 = plt.subplot(244, polar=True)         # 第4个,极坐标图(polar=True等价于projection='polar')
ax5 = plt.subplot(212, projection='3d')    # 2行1列,第2个位置,三维图

plt.tight_layout()                                     # 紧缩四周空白
plt.subplots_adjust(wspace=0.1, hspace=0.2)           # 调整子图间距

subplot(241) 怎么理解? 三个数字:2行、4列、第1个位置。241 = 2行4列第1个。

subplot(212) 怎么理解? 2行、1列、第2个位置。212 = 2行1列第2个。

五、设置图例样式

python 复制代码
t = np.arange(0.0, 2*np.pi, 0.01)  # 0到2π,步长0.01
s = np.sin(t)                       # 正弦值
c = np.cos(t)                       # 余弦值

plt.plot(t, s, label='正弦')        # 画正弦曲线,图例标签='正弦'
plt.plot(t, c, label='余弦')        # 画余弦曲线,图例标签='余弦'

plt.legend(prop=myfont,              # 图例字体
           title='Legend',          # 图例标题
           loc='lower left',        # 图例位置=左下角
           bbox_to_anchor=(0.43,0.75),  # 图例锚点坐标
           shadow=True,             # 显示阴影
           facecolor='yellowgreen', # 图例背景色=黄绿色
           edgecolor='red',         # 图例边框颜色=红色
           ncol=2,                  # 分两列显示
           markerfirst=False)       # 文字在前,符号在后

plt.show()

图例参数速查

参数 含义 大白话
prop 字体 用中文字体
title 图例标题 图例框上方的小标题
loc 位置 左下角、右上角等
shadow 阴影 图例框有没有阴影
facecolor 背景色 图例框里的背景颜色
edgecolor 边框色 图例框的边框颜色
ncol 列数 图例分几列显示
markerfirst 符号顺序 True=符号在前,False=文字在前

今日核心总结

  1. 雷达图 :用 plt.polar() 画,数据要首尾闭合。angles*180/np.pi 把弧度转角度。

  2. 三维图 :先导入 Axes3D,用 projection='3d' 声明。plot() 画曲线,plot_surface() 画曲面。

  3. 子图切分subplot(241) = 2行4列第1个。polar=True 画极坐标图。

  4. 图例样式loc 定位,facecolor 背景色,ncol 分栏,markerfirst 控制符号和文字的顺序。

注:已经使用DeepSeek进行整理精简核心内容,些许不理解的配合个人笔记进行理解。