查看全课大纲(第 6 / 45 节)
- 1.课程简介
- 2.环境搭建
- 3.预备知识
- 4.pyecharts初体验
- 5.数据可视化概述
- 6.数据可视化的目标和作用
- 7.数据可视化工具对比分析
- 8.数据可视化基本流程
- 9.数据可视化设计原则
- 10.pyecharts简介
- 11.官方图表样例
- 12.常用图表的基本结构
- 13.数据格式
- 14.图表的分类
- 15.柱状图与条形图
- 16.其他对比图表
- 17.常用配置项(一)
- 18.常用配置项(二)
- 19.折线图 面积图
- 20.K线图
- 21.其他时间图表
- 22.常用配置项
- 23.散点图 气泡图
- 24.热力图
- 25.其他相关性图表
- 26.饼图
- 27.矩形树图
- 28.其他成分比例图表
- 29.箱型图与直方图
- 30.3D柱状图与折线图
- 31.其他统计图表
- 32.地图 Map
- 33.地理坐标系Geo
- 34.3D 地图
- 35.网络关系图
- 36.主题河流图
- 37.词云图
- 38.组合图表组件
- 39.仪表盘相关图表
- 40.项目介绍
- 41.数据准备
- 42.子图制作(一)
- 43.子图制作(二)
- 44.数据大屏制作
- 45.项目总结
数据可视化的目标和作用
小象实战讲义 · ECharts 数据可视化
在上一节,我们了解了数据分析与可视化的基本概念。本节我们将聚焦于一个核心问题:我们为什么要做数据可视化?它究竟能为我们带来哪些不可替代的价值?我们将通过一个经典的统计学案例——“安斯库姆四重奏”,来直观地揭示可视化在洞察数据本质、避免分析陷阱方面的关键作用。
💡 核心导读
- 目标总结:明确数据可视化的四大核心目标:呈现复杂结果、辅助精准决策、加深理解记忆、高效传递信息。
- 经典案例:学习“安斯库姆四重奏”案例,理解仅依赖统计摘要(如均值、方差)分析数据可能带来的误导。
- 可视化威力:通过绘制散点图,直观展示四组统计特性一致的数据背后截然不同的分布模式。
- 实践过渡:本节将使用 Python 进行数据探索和初步可视化,为后续深入学习基于 Web 的交互式图表(ECharts/pyecharts)打下基础。
一、可视化的核心目标与作用
数据可视化远不止是“让图表更好看”。它是一种强大的沟通和分析工具,其核心目标可以总结为以下四点:
- 呈现复杂分析结果:将多维、复杂的分析结果,通过丰富的图表形式直观地呈现给读者,降低理解门槛。
- 辅助精准决策:让决策者能够快速、精准地洞察数据反映的趋势、占比、异常等关键信息,而无需费力解读枯燥的表格数字。
- 加深理解与记忆:“一图胜千言”。视觉化的信息比纯文本或数字更符合人类认知习惯,能有效加深受众对数据的理解和长期记忆。
- 高效传递信息与知识:以准确、高效、精简且全面的方式,在团队或受众间传递核心信息和知识,提升协作与沟通效率。
其中,第四点“准确而高效”尤为重要。它强调可视化不仅是“高效”的,更必须是“准确”的,要能真实反映数据背后的故事,避免因不当的分析方法而产生误导。接下来,我们将通过一个经典案例来深刻体会这一点。
二、经典案例:安斯库姆四重奏
“安斯库姆四重奏”(Anscombe‘s quartet)是统计学家弗朗西斯·安斯库姆(Francis Anscombe)于 1973 年构造的四组数据。它用一个极其巧妙的方式证明了:在分析数据之前先进行可视化检查是至关重要的,同时也揭示了离群值对统计结果的巨大影响。
这四组数据各有 11 个 (x, y) 数据点。如果我们仅计算一些常见的统计量,会得到一个惊人的结论。
让我们把安斯库姆四重奏的 44 个点显式写进 pandas DataFrame,不使用额外的统计绘图库。这样既能保证数据可复现,也方便后续直接交给 pyecharts。
import pandas as pd
base_x = [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5]
iv_x = [8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8]
series_y = {
"I": [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68],
"II": [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74],
"III": [7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73],
"IV": [6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89],
}
rows = []
for dataset, y_values in series_y.items():
x_values = iv_x if dataset == "IV" else base_x
rows.extend({"dataset": dataset, "x": x, "y": y} for x, y in zip(x_values, y_values))
anscombe_df = pd.DataFrame(rows)
print("数据集行数:", len(anscombe_df))
print("数据集预览(前12行):")
print(anscombe_df.head(12).to_string(index=False))
anscombe_df.info()
summary_stats = anscombe_df.groupby("dataset").agg(
x_mean=("x", "mean"),
x_var=("x", "var"),
y_mean=("y", "mean"),
y_var=("y", "var"),
)
summary_stats["correlation"] = anscombe_df.groupby("dataset")[["x", "y"]].apply(
lambda frame: frame["x"].corr(frame["y"])
)
print("四组数据的统计摘要:")
print(summary_stats.round(2).to_string())数据集行数: 44
数据集预览(前12行):
dataset x y
I 10 8.04
I 8 6.95
I 13 7.58
I 9 8.81
I 11 8.33
I 14 9.96
I 6 7.24
I 4 4.26
I 12 10.84
I 7 4.82
I 5 5.68
II 10 9.14
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 44 entries, 0 to 43
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 dataset 44 non-null str
1 x 44 non-null int64
2 y 44 non-null float64
dtypes: float64(1), int64(1), str(1)
memory usage: 1.2 KB
四组数据的统计摘要:
x_mean x_var y_mean y_var correlation
dataset
I 9.0 11.0 7.5 4.13 0.82
II 9.0 11.0 7.5 4.13 0.82
III 9.0 11.0 7.5 4.12 0.82
IV 9.0 11.0 7.5 4.12 0.82数据包含三列:dataset(数据集编号 I, II, III, IV)、x 和 y。总共 44 行,即每个数据集 11 个点。
上面的同一段代码已经同时计算了每组数据的 x 均值、y 均值、方差和相关系数,避免把统计与数据准备拆成互相依赖的两个代码块。
惊人的发现:从统计摘要来看,这四组数据几乎一模一样!
x的均值都是 9.0x的方差都是 11.0y的均值都是 7.5y的方差都是 ~4.13x与y的相关系数都是 ~0.82
如果仅凭这些数字做判断,我们很可能会认为这四组数据描述了相同的现象或关系。但事实果真如此吗?下面用 pyecharts 画出四组散点图,直接观察分布形态。
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Page, Scatter
from pyecharts.globals import CurrentConfig
CurrentConfig.ONLINE_HOST = "assets/"
base_x = [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5]
iv_x = [8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8]
series_y = {
"I": [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68],
"II": [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74],
"III": [7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73],
"IV": [6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89],
}
rows = []
for dataset, y_values in series_y.items():
x_values = iv_x if dataset == "IV" else base_x
rows.extend({"dataset": dataset, "x": x, "y": y} for x, y in zip(x_values, y_values))
anscombe_df = pd.DataFrame(rows)
page = Page(layout=Page.SimplePageLayout)
for dataset, group in anscombe_df.groupby("dataset"):
chart = (
Scatter()
.add_xaxis(group["x"].tolist())
.add_yaxis(f"数据集 {dataset}", group["y"].tolist())
.set_global_opts(
title_opts=opts.TitleOpts(title=f"安斯库姆四重奏 · 数据集 {dataset}"),
xaxis_opts=opts.AxisOpts(type_="value", name="x"),
yaxis_opts=opts.AxisOpts(type_="value", name="y"),
)
)
page.add(chart)
page.render("anscombe_quartet.html")代码会生成 anscombe_quartet.html,包含数据集 I、II、III、IV 的四张散点图。
视觉化揭示的真相:
- 数据集 I:看起来是“标准”的线性正相关,点大致沿直线分布。
- 数据集 II:呈现出明显的非线性关系(类似抛物线),但用直线去拟合会严重误导。
- 数据集 III:整体呈线性趋势,但存在一个明显的离群值。这个离群值极大地影响了回归线的位置。
- 数据集 IV:
x值几乎都集中在 8,只有一个点x=19远离其他点。这个极端的离群值“创造”出了虚假的高相关系数。
三、案例启示与可视化的重要性
安斯库姆四重奏给我们上了生动的一课:
- 统计摘要的局限性:均值、方差、相关系数等汇总统计量虽然简洁,但会丢失数据的分布形态、非线性关系以及离群值等关键信息,可能导致完全错误的结论。
- 可视化是不可或缺的探索步骤:在正式建模或下结论前,必须对数据进行可视化探索。图形能直观揭示数据中隐藏的模式、关系和问题,这是任何数字表格都无法替代的。
- 离群值需要特别关注:离群值(异常点)可能代表数据录入错误、测量误差,也可能代表有重大意义的特殊现象。可视化能帮助我们快速识别它们,并决定如何处理。
这正是数据可视化“准确而高效”传递信息的体现。它确保了我们在“高效”获取洞察的同时,不会因为方法缺陷而偏离“准确”的事实。
在本课程中,我们将学习使用 pyecharts(基于 ECharts)来创建交互式、可嵌入 Web 页面的图表。与上面演示的静态图相比,交互式图表允许用户缩放、拖拽、悬停查看数值,并能组合成复杂的仪表盘,在“数据大屏”等场景下发挥巨大威力。从下节课开始,我们将正式进入 pyecharts 的世界。
📝 动手练一练
- 数据提取:在不使用
groupby的情况下,编写代码分别提取出安斯库姆四重奏中“数据集 III”的所有数据点,并打印其x和y的值。
点击查看参考答案
# 方法1:使用布尔索引
dataset_iii = anscombe_df[anscombe_df['dataset'] == 'III']
print("数据集 III 的数据点:")
print(dataset_iii[['x', 'y']].to_string(index=False))
# 方法2:使用query方法
dataset_iii_query = anscombe_df.query("dataset == 'III'")
print("\n使用query方法得到的数据集 III:")
print(dataset_iii_query[['x', 'y']].values)数据集 III 的数据点:
x y
10.0 7.46
8.0 6.77
13.0 12.74
9.0 7.11
11.0 7.81
14.0 8.84
6.0 6.08
4.0 5.39
12.0 8.15
7.0 6.42
5.0 5.73
使用query方法得到的数据集 III:
[[10. 7.46]
[ 8. 6.77]
[13. 12.74]
[ 9. 7.11]
[11. 7.81]
[14. 8.84]
[ 6. 6.08]
[ 4. 5.39]
[12. 8.15]
[ 7. 6.42]
[ 5. 5.73]]- 离群值影响:手动计算数据集 III 在包含和不包含离群值(你认为哪个点是离群值?)两种情况下的
y的均值,体会离群值对统计量的影响。
点击查看参考答案
# 提取数据集 III
data_iii = anscombe_df[anscombe_df['dataset'] == 'III'].copy()
# 假设我们认为 (13.0, 12.74) 是离群值(y值明显偏大)
outlier_index = data_iii[data_iii['x'] == 13.0].index[0]
data_iii_without_outlier = data_iii.drop(index=outlier_index)
mean_y_with = data_iii['y'].mean()
mean_y_without = data_iii_without_outlier['y'].mean()
print(f"包含离群值时 y 的均值: {mean_y_with:.2f}")
print(f"去除离群值后 y 的均值: {mean_y_without:.2f}")
print(f"离群值使均值增大了: {mean_y_with - mean_y_without:.2f}")包含离群值时 y 的均值: 7.50
去除离群值后 y 的均值: 6.98
离群值使均值增大了: 0.52本章小结
本节我们深入探讨了数据可视化的根本目标,并通过“安斯库姆四重奏”这一经典案例,直观感受到了可视化在数据探索与分析中的决定性作用。记住,图表不仅是结果的展示,更是发现真相的工具。
📋 行动清单
- 理解并复述数据可视化的四大核心作用。
- 运行并理解安斯库姆四重奏的代码,观察统计摘要与可视化图形的巨大差异。
- 思考在你过去或当前的项目中,是否有仅依赖数字表格做决策而可能忽略数据真实分布的情况?
—— 小象教研组
