一、绘制雷达图
业务场景:把学生的各科成绩画成雷达图,让用人单位一眼看出综合能力。
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=文字在前 |
今日核心总结
-
雷达图 :用
plt.polar()画,数据要首尾闭合。angles*180/np.pi把弧度转角度。 -
三维图 :先导入
Axes3D,用projection='3d'声明。plot()画曲线,plot_surface()画曲面。 -
子图切分 :
subplot(241)= 2行4列第1个。polar=True画极坐标图。 -
图例样式 :
loc定位,facecolor背景色,ncol分栏,markerfirst控制符号和文字的顺序。
注:已经使用DeepSeek进行整理精简核心内容,些许不理解的配合个人笔记进行理解。