数据分析的目的,并不只是得到若干计算结果,更重要的是把结果清楚表达出来。

一组平均值、一个分组统计表、若干类别分布数据,若只是停留在表格中,往往不利于快速理解;而经过适当可视化(Visualization)后,数据中的差异、分布、层次和比例关系就会更加直观。

Pandas 提供了基于 plot() 的内置绘图接口,可以直接从 DataFrame 或 Series 快速生成常见图形。

本文围绕学生成绩数据,介绍如何用 Pandas 展示数量变化、类别分布、数据分布特征以及分组结果,并进一步说明如何从快速绘图过渡到更专业的可视化工具。

下面先构造本篇所需的示例数据:

import pandas as pd
scores = pd.DataFrame([    {"学号": "S001", "姓名": "张三", "班级": "C01", "语文": 88, "数学": 92, "英语": 85},    {"学号": "S002", "姓名": "李四", "班级": "C01", "语文": 76, "数学": 81, "英语": 79},    {"学号": "S003", "姓名": "王五", "班级": "C02", "语文": 90, "数学": 87, "英语": 93},    {"学号": "S004", "姓名": "赵六", "班级": "C02", "语文": 85, "数学": 89, "英语": 88},    {"学号": "S005", "姓名": "孙七", "班级": "C03", "语文": 91, "数学": 95, "英语": 90},    {"学号": "S006", "姓名": "周八", "班级": "C03", "语文": 78, "数学": 84, "英语": 80}])

一、为什么分析结果需要可视化

分析的任务,是把数据转化为结论;而表达的任务,是让这些结论能够被快速理解。

表格适合保存完整信息,但在以下情形中,图形通常更有优势:

• 比较大小关系

• 观察变化趋势

• 展示分布特征

• 呈现类别占比

• 对比分组结果

例如,一组班级平均分数据,若直接写成数字,读者仍需逐项比较;而若绘制为柱状图,差异会更加直观。

因此,可视化不是装饰,而是数据表达的重要组成部分。

二、从表格直接生成图形

Pandas 中最常见的绘图入口是 plot()。

它基于 Matplotlib,因此可以直接对 Series 或 DataFrame 进行快速绘图。

1、绘制单列图形

例如,绘制数学成绩:

scores["数学"].plot()

在 Notebook 等交互环境中,图形通常可以直接显示;而在普通脚本环境中,往往还需要导入 matplotlib.pyplot 并调用 plt.show()。若图中包含中文,还常需要事先设置中文字体。

import matplotlib.pyplot as plt
# 设置中文字体plt.rcParams["font.sans-serif"] = ["SimHei"]      # 黑体plt.rcParams["axes.unicode_minus"] = False        # 解决负号显示问题
plt.show()

2、绘制多列图形

例如,比较三门课成绩:

scores[["语文", "数学", "英语"]].plot()

3、指定图形类型

可通过 kind 参数指定图形类型:

scores["数学"].plot(kind="bar")

常见类型包括:

• line:折线图

• bar:柱状图

• barh:横向柱状图

• hist:直方图

• box:箱线图

• pie:饼图

这也是 Pandas 绘图适合作为可视化起点的重要原因。

三、展示数值比较与相对变化

当分析任务关注“数值大小规律”时,柱状图和折线图最常用。

1、使用柱状图比较各学生数学成绩

scores.plot(x="姓名", y="数学", kind="bar")

柱状图适合比较离散对象之间的数值高低。

2、使用折线图观察连续变化

若希望按记录顺序观察不同对象之间的相对起伏,也可以使用折线图:

scores.plot(x="姓名", y=["语文", "数学", "英语"], kind="line")

需要注意,若横轴并非时间或连续变量,折线图更多体现的是按当前顺序连接后的相对变化,而不一定表示真实趋势。

3、图形选择原则

比较离散个体:柱状图更合适

观察变化过程:折线图更合适

因此,图形类型应与分析目标保持一致,而不是随意选择。

四、展示类别分布与占比关系

对于类别数据,常需要展示“各类有多少”以及“各类占多少”。

1、展示班级人数分布

scores["班级"].value_counts().plot(kind="bar")

这适合展示各班人数差异。

2、展示班级占比关系

scores["班级"].value_counts().plot(kind="pie", autopct="%.1f%%")

饼图适合展示总体中各部分所占比例,但类别不宜过多,否则标签与扇区都不易辨认。若类别较多或各部分差异较小,柱状图通常比饼图更易比较。

3、对成绩等级作分类后展示

scores["数学等级"] = pd.cut(    scores["数学"],    bins=[0, 79, 89, 100],    labels=["一般(0~79)", "良好(80~89)", "优秀(90~100)"])
scores["数学等级"].value_counts(sort=False).plot(kind="bar")

这类图形能够把连续成绩转化为类别结果,更适合用于说明分布层级。

五、观察数据的分布特征

当分析任务关注“数据是集中还是分散”“是否存在明显偏态或异常值”时,应使用分布图形。

1、直方图

scores["数学"].plot(kind="hist", bins=5)

直方图适合观察数值的大致分布情况。

2、箱线图

scores[["语文", "数学", "英语"]].plot(kind="box")

箱线图强调的是分布摘要,而不是逐个展示每一个原始数据点。

箱线图适合观察:

• 中位数位置

• 四分位范围

• 离散程度

• 是否存在明显离群点

平均值只能告诉我们“中心大致在哪”,但分布图能够进一步告诉我们“数据是如何分散的”。这对分析结果的解释非常重要。

六、用图形展示分组统计结果

可视化通常不是替代统计,而是建立在统计结果之上的表达方式。

分组统计往往是分析中的核心环节,而图形能够显著提升分组结果的可读性。

1、绘制各班平均数学成绩

class_mean = scores.groupby("班级")["数学"].mean()class_mean.plot(kind="bar")

2、比较各班三门课平均成绩

class_subject_mean = scores.groupby("班级")[["语文", "数学", "英语"]].mean()class_subject_mean.plot(kind="bar")

这种图形能够同时展示:

• 组间差异

• 指标间差异

表格中的分组均值虽然准确,但并不总是直观。

转换为图形后,班级之间、科目之间的差异会更加清楚,尤其适合汇报与展示。

七、从快速绘图走向专业可视化

Pandas 的 plot() 很适合快速探索和教学演示,但在更复杂场景中,还可以进一步使用专业绘图库。

1、Pandas 绘图的优势

• 语法简洁

• 直接基于 DataFrame

• 适合快速查看结果

• 适合常见统计图

2、Pandas 绘图的局限

• 细节控制相对有限

• 图形美化能力不如专业库

• 多图布局、主题样式和高级注释支持有限

3、向 Matplotlib 与 Seaborn 过渡

一般可按如下分工理解:

• Pandas:快速从表格生成基础图形

• Matplotlib:底层控制与精细定制

• Seaborn:更高级的统计图形与更美观的默认样式

因此,Pandas 内置绘图可视为可视化的起点,而不是终点。

八、综合示例

前文主要介绍了 Pandas 的快速绘图方式。下面进一步通过两个简单示例说明:当需要更细的图形控制或更统计化的展示时,可以如何借助 Matplotlib 与 Seaborn 完成结果展示。

示例 1:使用 Matplotlib 展示班级平均成绩

import matplotlib.pyplot as plt
# 设置中文字体plt.rcParams["font.sans-serif"] = ["SimHei"]  # 黑体plt.rcParams["axes.unicode_minus"] = False    # 解决负号显示问题
class_subject_mean = scores.groupby("班级")[["语文", "数学", "英语"]].mean()
class_subject_mean.plot(kind="bar")plt.title("各班三门课平均分")plt.xlabel("班级")plt.ylabel("平均分")plt.grid(axis="y", linestyle="--", alpha=0.5)plt.show()

Matplotlib 示例体现了更细的标题、坐标轴、网格控制。

示例 2:使用 Seaborn 展示分组比较结果

import seaborn as snsimport matplotlib.pyplot as plt
# 设置中文字体plt.rcParams["font.sans-serif"] = ["SimHei"]  # 黑体plt.rcParams["axes.unicode_minus"] = False    # 解决负号显示问题
long_scores = scores.melt(    id_vars=["学号", "姓名", "班级"],    value_vars=["语文", "数学", "英语"],    var_name="科目",    value_name="成绩")
# sns.barplot() 默认会对同组数据进行聚合,通常显示均值,因此适合用于分组比较sns.barplot(data=long_scores, x="班级", y="成绩", hue="科目")plt.title("各班各科成绩比较")plt.show()

Seaborn 的很多统计图在长表结构下更自然。

📘 小结

可视化的价值,不在于把数据“画出来”,而在于把分析结果更清楚地表达出来。只有根据任务选择合适的图形,并结合统计结果组织展示,数据中的差异、分布和结构特征才能被更直观地理解。

延伸阅读:

《人工智能通识课:Matplotlib 绘图基础》

《Seaborn 绘图基础》

图片

“点赞有美意,赞赏是鼓励”

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐