第15章 报表程序 - 让数据说话
引言:从数字到图表
想象一下,如果你是一名老师,手里有一份学生的考试成绩单,上面只有密密麻麻的数字:
小明: 语文85 数学92 英语78
小红: 语文90 数学88 英语95
小刚: 语文78 数学85 英语82
...
你能快速看出:
- 哪个科目最难?
- 每个学生的强项是什么?
- 全班的平均成绩如何?
如果把这些数字画成图表,比如柱状图或折线图,答案就会一目了然!这就是数据可视化的作用——把枯燥的数字变成直观的图形,让数据“说话“。
什么是报表程序?
报表程序就是用来收集、处理和展示数据的程序。在我们的日常生活中:
- 天气预报:用折线图显示未来一周的气温变化
- 股票软件:用K线图显示股票价格波动
- 运动APP:用饼图显示你今天的运动时间分配
- 游戏排行榜:用柱状图显示玩家积分排名
这些程序都有一个共同点:把数据变成图表,让人更容易理解数据背后的信息。
为什么学习报表程序?
学习制作报表程序,你将掌握:
- 数据处理能力:学会整理和分析数据
- 可视化思维:学会用图形表达信息
- 实用工具:能制作出真正有用的程序
比如,你可以:
- 制作班级成绩分析报告
- 记录自己的零花钱使用情况
- 统计家里的电费水费变化
- 分析自己喜欢的游戏数据
本章学习路线
本章将教你如何使用pyecharts库制作各种图表,同时融入数学统计知识:
第1步: 安装和配置pyecharts库
↓
第2步: 复习数学统计知识(平均数、中位数、众数)
↓
第3步: 柱状图 - 比较不同类别的数据
↓
第4步: 折线图 - 显示数据的变化趋势
↓
第5步: 饼图 - 显示各部分占整体的比例
↓
第6步: 综合项目 - 制作完整的数据报表
👨🏫 给家长的小贴士
- 数据可视化是现代信息时代的重要技能
- 图表能培养孩子的抽象思维能力
- 本章重点融入小学数学统计知识:平均数、中位数、众数、数据分组
- 建议选择孩子感兴趣的数据(如游戏数据、运动数据)作为练习素材
- 鼓励孩子用图表解决实际问题(如班级统计、家庭记账)
- 数学知识点提醒:
- 平均数 = 总数 ÷ 个数
- 中位数:数据从大到小排列,中间位置的数
- 众数:出现次数最多的数
- 方差:数据波动大小的衡量(本章会简单介绍)
15.1 认识pyecharts库
15.1.1 什么是pyecharts?
pyecharts是一个专门用于生成图表的Python库。它的名字可以拆解为:
- py: Python的缩写
- echarts: 百度开源的一个强大图表工具
- s: 表示这是echarts的Python版本
为什么要使用pyecharts?
- 功能强大: 支持几十种图表类型
- 美观漂亮: 生成的图表配色和样式都很专业
- 易于使用: 只需要几行代码就能生成图表
- 交互式: 生成的图表支持鼠标悬停、点击缩放等操作
15.1.2 安装pyecharts
在开始使用pyecharts之前,需要先安装它。还记得我们在第13章学过的pip工具吗?
步骤1: 打开命令行窗口
Windows系统:
- 按Win+R键
- 输入
cmd - 按回车键
Mac系统:
- 按Command+空格键
- 输入“终端“
- 按回车键
步骤2: 安装pyecharts
在命令行窗口中输入以下命令:
pip install pyecharts
你会看到类似这样的输出:
Collecting pyecharts
Downloading pyecharts-2.0.4-py3-none-any.whl (...)
Installing collected packages: pyecharts
Successfully installed pyecharts-2.0.4
步骤3: 验证安装
安装完成后,在Python中输入以下代码测试:
from pyecharts.charts import Bar
print("pyecharts安装成功!")
如果输出“pyecharts安装成功!“说明安装成功了!
步骤4: (可选)安装图片快照功能
如果你想直接把图表保存为图片格式,需要安装额外的插件:
pip install pyecharts_snapshot
这个功能可以把HTML格式的图表转换为PNG或JPG图片。
给家长的小贴士
- pip安装失败: 可能是因为网络问题,可以尝试使用国内镜像源:
pip install pyecharts -i https://pypi.tuna.tsinghua.edu.cn/simple- 权限问题: 如果提示权限不足,在Windows上以管理员身份运行命令行,Mac上使用sudo
- 版本问题: pyecharts有v1和v2两个版本,本书使用v2版本
- 离线安装: 如果网络不好,可以下载whl文件后本地安装
常见问题解答
Q: 为什么要安装这么大的库? A: pyecharts包含了大量的图表模板和样式文件,所以比较大。但这些文件让我们能做出更专业的图表。
Q: 安装失败怎么办? A: 1) 检查网络连接 2) 尝试升级pip:
python -m pip install --upgrade pip3) 使用国内镜像源Q: 每次使用都要重新安装吗? A: 不需要!安装一次后,以后在任何Python程序中都可以使用。
15.1.3 pyecharts的基本使用流程
使用pyecharts生成图表一般分为5个步骤:
# 步骤1: 导入需要的图表类
from pyecharts.charts import Bar
# 步骤2: 创建图表对象
bar = Bar()
# 步骤3: 添加数据
bar.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
bar.add_yaxis("商家A", [5, 20, 36, 10, 10, 100])
# 步骤4: 设置全局选项(可选)
bar.set_global_opts(title_opts={"text": "我的第一个图表"})
# 步骤5: 渲染生成HTML文件
bar.render("my_first_chart.html")
代码解析:
- 导入: 从pyecharts.charts导入你需要的图表类(如Bar、Line、Pie)
- 创建: 创建一个图表对象
- 数据: 用add_xaxis()添加x轴数据,用add_yaxis()添加y轴数据
- 选项: 设置标题、图例、工具箱等配置
- 渲染: 生成一个HTML文件,用浏览器打开就能看到图表
运行结果:
程序运行后,会在当前目录下生成my_first_chart.html文件。双击这个文件,浏览器会打开它,你就能看到一个漂亮的柱状图了!
给家长的小贴士
- HTML文件: 生成的图表是网页格式(HTML),不需要额外安装软件就能打开
- 代码结构: 强调“导入-创建-添加数据-设置选项-渲染“这5步固定流程
- 逐步演示: 建议先让孩子看完整的运行效果,激发学习兴趣
- 文件位置: 提醒孩子注意HTML文件的保存位置,方便查找
实践练习1:修改数据
任务: 将上面的代码复制下来,修改数据:
- x轴改成你喜欢的6种水果
- y轴改成每种水果的价格(元)
- 标题改成“水果价格表“
提示:
bar.add_xaxis(["苹果", "香蕉", "橙子", "草莓", "葡萄", "西瓜"]) bar.add_yaxis("价格", [8, 3, 6, 15, 12, 5])答案:
点击查看完整代码
from pyecharts.charts import Bar # 创建图表对象 bar = Bar() # 添加数据 bar.add_xaxis(["苹果", "香蕉", "橙子", "草莓", "葡萄", "西瓜"]) bar.add_yaxis("价格(元)", [8, 3, 6, 15, 12, 5]) # 设置标题 bar.set_global_opts(title_opts={"text": "水果价格表"}) # 生成图表 bar.render("fruit_price.html")运行后打开
fruit_price.html,你就能看到水果价格的柱状图了!
15.2 数学统计知识复习 📊
在开始制作图表之前,让我们先复习一些数学统计知识。这些知识会在制作图表时经常用到!
15.2.1 平均数(Average)
什么是平均数?
平均数是一组数据的“代表值“,它能反映这组数据的整体水平。
🍎 生活中的例子: 假设你有5个苹果,分别重: 150克、160克、140克、155克、145克。
计算平均数的步骤:
# 步骤1: 把所有数据加起来
total = 150 + 160 + 140 + 155 + 145
print("总重量:", total) # 输出: 750克
# 步骤2: 除以数据的个数
average = total / 5
print("平均重量:", average) # 输出: 150克
用Python计算平均数:
# 一组数据
scores = [85, 90, 78, 92, 88]
# 方法1: 使用sum()和len()
average = sum(scores) / len(scores)
print(f"平均分: {average}")
# 方法2: 用循环计算
total = 0
for score in scores:
total += score
average = total / len(scores)
print(f"平均分: {average}")
平均数的数学意义:
- 如果每个人的成绩都等于平均分,那么总分不会变
- 平均数是“公平“的体现——每个人贡献相同
👨🏫 给家长的小贴士
- 平均数 vs 总数: 问孩子“为什么有了总数还要算平均数?“(因为人数不同时,总数不能直接比较)
- 生活中的平均数: 平均气温、平均身高、平均速度、平均价格
- 计算技巧: 先估算,再精确计算。比如[85, 90, 78, 92, 88],可以估算“大约85左右“
- 错误认知: 平均数不一定是数据中的某个值(比如[1, 2, 10],平均数是4.33,不在原数据中)
15.2.2 中位数(Median)
什么是中位数?
中位数是把数据按大小排列后,位于中间位置的那个数。
🏃 生活中的例子: 跑步比赛,5个人的成绩是:
- 3分20秒、3分15秒、3分25秒、3分18秒、3分22秒
找中位数的步骤:
# 步骤1: 把数据从小到大排列
times = [3*60+15, 3*60+18, 3*60+20, 3*60+22, 3*60+25] # 转换为秒
print("排序前:", times)
# 使用Python排序
times_sorted = sorted(times)
print("排序后:", times_sorted) # [195, 198, 200, 202, 205]
# 步骤2: 找中间位置的数据(第3个)
median_index = len(times_sorted) // 2 # 5//2 = 2(索引从0开始)
median = times_sorted[median_index]
print(f"中位数: {median}秒,即{median//60}分{median%60}秒")
中位数的特点:
- 数据个数是奇数时,中位数就是中间的那个数
- 数据个数是偶数时,中位数是中间两个数的平均数
偶数个数据的例子:
# 6个数据
scores = [85, 90, 78, 92, 88, 95]
# 排序
scores_sorted = sorted(scores) # [78, 85, 88, 90, 92, 95]
# 中间两个数: 第3个(88)和第4个(90)
middle1 = scores_sorted[2] # 第3个,索引为2
middle2 = scores_sorted[3] # 第4个,索引为3
median = (middle1 + middle2) / 2
print(f"中位数: {median}") # 输出: 89.0
中位数的数学意义:
- 中位数不受极端值(太大或太小的数)的影响
- 比如工资统计,如果有一个人工资特别高,平均数会失真,但中位数能反映真实情况
👨🏫 给家长的小贴士
- 平均数 vs 中位数: 举例说明差异
- 班级成绩: [60, 85, 88, 90, 92],平均数=83,中位数=88(接近)
- 班级成绩: [10, 85, 88, 90, 92],平均数=73,中位数=88(差异大)
- 什么时候用中位数: 当有极端值(异常大或异常小的数据)时
- 排序技能: 教孩子手动排序的方法(冒泡排序的简化版)
- 找位置: 奇数个数据的位置 = (总数+1)÷2,偶数个数据取中间两个的平均
15.2.3 众数(Mode)
什么是众数?
众数是一组数据中出现次数最多的数。
🎨 生活中的例子: 班级同学最喜欢的颜色统计:
- 红色:5人、蓝色:8人、绿色:3人、黄色:8人、紫色:2人
# 数据
colors = ["红", "蓝", "绿", "黄", "紫"]
counts = [5, 8, 3, 8, 2]
# 找最大值
max_count = max(counts)
print(f"最多人选的人数: {max_count}")
# 找最大值的位置
max_index = counts.index(max_count)
mode_color = colors[max_index]
print(f"众数(最受欢迎的颜色): {mode_color}")
多个众数的情况:
# 数据: [1, 2, 2, 3, 3, 4]
# 2出现2次,3也出现2次
# 这组数据有"双众数": 2和3
# 统计每个数出现的次数
from collections import Counter
data = [1, 2, 2, 3, 3, 4]
count_result = Counter(data)
print("统计结果:", count_result) # Counter({2: 2, 3: 2, 1: 1, 4: 1})
# 找出现最多的次数
max_count = max(count_result.values())
# 找所有众数
modes = [num for num, count in count_result.items() if count == max_count]
print(f"众数: {modes}") # 输出: [2, 3]
众数的特点:
- 一组数据可能没有众数(所有数都只出现1次)
- 一组数据可能有多个众数
- 众数一定是数据中的某个值(这一点和平均数不同!)
👨🏫 给家长的小贴士
- 众数 vs 平均数: 众数关注“最多“,平均数关注“整体“
- 投票选举: 众数就像民主投票,得票最多的当选
- 实际应用:
- 商店进货哪种商品(卖得最好的)
- 鞋厂生产哪种尺码(穿的人最多的)
- 编程思维: 用字典统计频次是常见的数据处理方法
15.2.4 数据分组(区间统计)
什么是数据分组?
当数据很多时,我们不会逐个统计,而是把数据分成几个区间(范围),统计每个区间有多少个数据。
📊 生活中的例子:
统计班级50个学生的考试成绩:
- 100分: 3人
- 90-99分: 12人
- 80-89分: 20人
- 70-79分: 10人
- 60-69分: 4人
- 60分以下: 1人
用Python实现数据分组:
# 原始成绩数据
scores = [95, 87, 92, 78, 85, 90, 88, 92, 85, 76,
82, 89, 91, 85, 88, 90, 87, 85, 92, 88]
# 定义分数段
ranges = ["优秀(90-100)", "良好(80-89)", "及格(60-79)", "不及格(0-59)"]
counts = [0, 0, 0, 0]
# 统计每个分数段的人数
for score in scores:
if score >= 90:
counts[0] += 1
elif score >= 80:
counts[1] += 1
elif score >= 60:
counts[2] += 1
else:
counts[3] += 1
print("分数段分布:")
for i in range(len(ranges)):
print(f"{ranges[i]}: {counts[i]}人")
数据分组的数学意义:
- 简化数据,让数据更容易理解
- 保留数据的整体趋势,同时忽略细节
- 方便制作统计图表(直方图、饼图)
分组的技巧:
- 等距分组: 每个区间的长度相同(如0-10, 10-20, 20-30)
- 有意义分组: 根据实际意义划分(如成绩的优、良、及格)
- 边界明确: 明确区间的起点和终点(包括端点吗?)
👨🏫 给家长的小贴士
- 为什么分组: 问孩子“50个人的成绩,逐个柱状图会很拥挤,怎么办?“(引出分组)
- 选择区间: 举例说明区间太大或太小的问题
- 太大: [0-100]只有一个区间,没意义
- 太小: [0-1, 1-2, 2-3…]太细碎
- 合适: [0-59, 60-69, 70-79, 80-89, 90-100]
- 包含边界: 90分属于哪个区间?需要约定(通常“左闭右开“[90,100)或“左开右闭“(89,100])
- 图表对应: 分组数据适合做饼图,显示各部分占比
15.2.5 综合练习:数据分析
现在让我们用刚才学到的统计知识,分析一组真实数据!
📚 案例分析:班级阅读情况统计
# 班级同学这学期阅读的书籍数量
books_read = [5, 8, 12, 6, 7, 10, 9, 8, 15, 6,
7, 8, 9, 11, 7, 8, 10, 12, 8, 9]
# 1. 计算平均数
average = sum(books_read) / len(books_read)
print(f"平均每人读{average:.1f}本书")
# 2. 找中位数
sorted_books = sorted(books_read)
n = len(sorted_books)
if n % 2 == 1: # 奇数个
median = sorted_books[n // 2]
else: # 偶数个
median = (sorted_books[n // 2 - 1] + sorted_books[n // 2]) / 2
print(f"中位数: {median}本")
# 3. 找众数
from collections import Counter
count_result = Counter(books_read)
max_count = max(count_result.values())
modes = [num for num, count in count_result.items() if count == max_count]
print(f"众数: {modes}本")
# 4. 数据分组
ranges = ["0-5本", "6-10本", "11-15本", "16本以上"]
counts = [0, 0, 0, 0]
for books in books_read:
if books <= 5:
counts[0] += 1
elif books <= 10:
counts[1] += 1
elif books <= 15:
counts[2] += 1
else:
counts[3] += 1
print("\n阅读量分组统计:")
for i in range(len(ranges)):
percentage = counts[i] / len(books_read) * 100
print(f"{ranges[i]}: {counts[i]}人,占{percentage:.1f}%")
运行结果:
平均每人读8.7本书
中位数: 8.0本
众数: [8]本
阅读量分组统计:
0-5本: 1人,占5.0%
6-10本: 15人,占75.0%
11-15本: 4人,占20.0%
16本以上: 0人,占0.0%
数据分析结论:
- 大部分同学(75%)阅读量在6-10本之间
- 平均数(8.7本)和中位数(8本)接近,说明数据分布比较均匀
- 众数是8本,说明阅读8本的同学最多
- 全班没有一个人阅读超过15本,但也没有一个人阅读少于6本(除了1人)
👨🏫 给家长的小贴士
- 数据思维: 教孩子从数据中“读故事“,而不是只看数字
- 多角度分析: 平均数、中位数、众数各有用处,综合分析更全面
- 批判性思维: 问孩子“如果你是老师,看到这个数据会怎么做?“(比如:组织读书分享会)
- 现实应用: 鼓励孩子用这套方法分析自己的数据(游戏时长、学习时间等)
- 编程价值: 强调Python让数据分析变得简单高效,手算20个数据要很久,Python只需要几秒
🎯 实践练习2:你自己的数据分析
任务: 收集一组你感兴趣的数据,并用Python分析:
数据主题建议:
- 游戏数据: 最近10次游戏的得分/等级
- 运动数据: 最近2周每天的运动时长
- 学习数据: 最近10次作业的分数
- 创意数据: 其他你感兴趣的数据
要求:
- 至少10个数据点
- 计算平均数、中位数、众数
- 进行数据分组(至少3个区间)
- 写出分析结论(至少3条)
答案示例:
点击查看参考答案
# 示例:游戏得分分析 scores = [85, 92, 78, 88, 95, 82, 90, 87, 91, 89] # 平均数 avg = sum(scores) / len(scores) print(f"平均分: {avg:.1f}") # 中位数 sorted_scores = sorted(scores) median = (sorted_scores[4] + sorted_scores[5]) / 2 print(f"中位数: {median}") # 众数 from collections import Counter count_result = Counter(scores) max_count = max(count_result.values()) modes = [s for s, c in count_result.items() if c == max_count] print(f"众数: {modes}") # 数据分组 ranges = ["优秀(90-100)", "良好(80-89)", "及格(60-79)", "不及格(0-59)"] counts = [0, 0, 0, 0] for score in scores: if score >= 90: counts[0] += 1 elif score >= 80: counts[1] += 1 elif score >= 60: counts[2] += 1 else: counts[3] += 1 print("\n分数段分布:") for i in range(len(ranges)): print(f"{ranges[i]}: {counts[i]}人")
15.3 柱状图 - 比较大小的高手
15.3.1 柱状图的应用场景
**柱状图(Bar Chart)**是最常见的图表类型之一,它用柱子的高度来表示数据的大小。
柱状图适合用来:
- 比较不同类别: 比较不同产品的销量
- 排名: 显示班级成绩排名
- 统计: 统计每个月的零花钱支出
生活中的柱状图例子:
- 奥运会奖牌榜
- 游戏英雄战斗力对比
- 各城市人口数量对比
15.3.2 创建一个简单的柱状图
让我们从最简单的例子开始——制作一个班级成绩的柱状图:
from pyecharts.charts import Bar
# 创建柱状图
bar = Bar()
# 添加x轴数据(学生姓名)
bar.add_xaxis(["小明", "小红", "小刚", "小丽", "小华"])
# 添加y轴数据(语文成绩)
bar.add_yaxis("语文成绩", [85, 90, 78, 92, 88])
# 设置标题
bar.set_global_opts(title_opts={"text": "班级语文成绩"})
# 生成HTML文件
bar.render("class_scores.html")
运行结果:
程序会生成class_scores.html文件,用浏览器打开后,你会看到5个不同高度的柱子,每个柱子代表一个学生的语文成绩。
15.3.3 添加多个系列的数据
有时候我们需要对比多组数据。比如,想同时显示每个学生的语文、数学、英语成绩:
from pyecharts.charts import Bar
bar = Bar()
# 添加x轴(学生姓名)
bar.add_xaxis(["小明", "小红", "小刚", "小丽", "小华"])
# 添加多组数据
bar.add_yaxis("语文", [85, 90, 78, 92, 88])
bar.add_yaxis("数学", [92, 88, 85, 95, 90])
bar.add_yaxis("英语", [78, 95, 82, 88, 91])
# 设置标题
bar.set_global_opts(title_opts={"text": "班级成绩表"})
# 生成图表
bar.render("class_scores_all.html")
图表解读:
- 每个学生会有3根柱子,分别代表语文、数学、英语成绩
- 不同颜色的柱子代表不同的科目
- 图表右上角会显示图例(语文、数学、英语),点击可以隐藏/显示对应的数据
给家长的小贴士
- 颜色区分: 帮助孩子理解不同颜色代表不同数据系列
- 图例功能: 演示点击图例可以隐藏/显示数据,这是pyecharts的交互功能
- 数据对应: 确保x轴和y轴的数据数量一致,否则会报错
- 中文字符: pyecharts完全支持中文,不会出现乱码问题
实践练习2:最喜欢的运动统计
任务: 调查班级同学最喜欢的运动,制作柱状图:
- x轴: 篮球、足球、羽毛球、乒乓球、跑步、游泳
- y轴: 喜欢该项运动的人数(假设为: 15, 12, 8, 10, 6, 9)
- 标题: “班级运动喜好调查”
要求:
- 添加y轴名称:“人数”
- 添加数据标签显示每个柱子上的具体数值
答案:
点击查看完整代码
from pyecharts.charts import Bar from pyecharts import options as opts bar = Bar() # 添加数据 bar.add_xaxis(["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"]) bar.add_yaxis( series_name="人数", yaxis_data=[15, 12, 8, 10, 6, 9], label_opts=opts.LabelOpts(is_show=True) # 显示数据标签 ) # 设置全局选项 bar.set_global_opts( title_opts={"text": "班级运动喜好调查"}, yaxis_opts=opts.AxisOpts(name="人数"), xaxis_opts=opts.AxisOpts(name="运动项目") ) # 生成图表 bar.render("sports_survey.html")运行后,每个柱子上会显示具体人数,方便读取数据!
15.3.4 柱状图的高级设置
1. 水平柱状图
默认的柱状图是垂直的,柱子从下往上。有时我们需要水平的柱状图,柱子从左往右:
from pyecharts.charts import Bar
from pyecharts import options as opts
bar = Bar()
# 添加数据(反转x和y轴的添加顺序)
bar.add_xaxis(["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"])
bar.add_yaxis("人数", [15, 12, 8, 10, 6, 9])
# 设置全局选项
bar.set_global_opts(
title_opts={"text": "班级运动喜好调查"},
yaxis_opts=opts.AxisOpts(name="人数"),
xaxis_opts=opts.AxisOpts(name="运动项目")
)
# 反转x轴和y轴
bar.reversal_axis()
# 生成图表
bar.render("horizontal_bar.html")
使用场景: 水平柱状图适合类别名称很长的情况(如“数学竞赛成绩“、“英语演讲比赛“等),避免文字重叠。
2. 堆叠柱状图
堆叠柱状图可以让多组数据叠加显示:
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
# 使用主题
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
bar.add_xaxis(["第一季度", "第二季度", "第三季度", "第四季度"])
bar.add_yaxis("电子产品", [10, 20, 30, 40], stack="stack1")
bar.add_yaxis("服装", [15, 25, 20, 35], stack="stack1")
bar.add_yaxis("食品", [20, 15, 25, 30], stack="stack1")
bar.set_global_opts(
title_opts={"text": "季度销售额"},
yaxis_opts=opts.AxisOpts(name="销售额(万元)"),
xaxis_opts=opts.AxisOpts(name="季度"),
toolbox_opts=opts.ToolboxOpts(is_show=True) # 显示工具栏
)
bar.render("stacked_bar.html")
使用场景: 堆叠柱状图适合显示部分与整体的关系,比如每天不同类别商品的销售总额。
给家长的小贴士
- 主题样式: pyecharts提供了多个主题(LIGHT, DARK, ROMA等),可以尝试不同风格
- 工具栏: toolbox_opts会显示下载图片、数据视图等功能,很实用
- 堆叠概念: 用积木叠高高来类比堆叠柱状图,孩子更容易理解
- 代码复用: 鼓励孩子把常用配置保存起来,下次直接使用
15.3.5 柱状图的常见问题
问题1: 中文显示乱码
虽然pyecharts默认支持中文,但如果你的Python文件编码不是UTF-8,可能会出现乱码。
解决方法: 在Python文件的第一行添加:
# -*- coding: utf-8 -*-
问题2: 柱子太多显示不下
当x轴的类别太多时,柱子会挤在一起。
解决方法:
bar.set_global_opts(
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(rotate=45) # 旋转标签45度
)
)
问题3: 数值差异太大
如果一组数据是[5, 8, 10],另一组是[1000, 2000, 3000],数值小的柱子几乎看不见。
解决方法: 使用双y轴(在高级应用中会学习)或调整数据比例。
实践练习3:比较自己和偶像的数据
任务: 制作一个柱状图,对比你和偶像的数据(可以是游戏、运动、学习等):
- 要求:至少3个对比项目(如:身高、体重、年龄,或游戏等级、胜率、场次)
- 使用水平柱状图
- 添加标题和数据标签
示例数据:
me = [165, 50, 12] # 身高cm, 体重kg, 年龄 idol = [178, 65, 25] items = ["身高(cm)", "体重(kg)", "年龄"]答案:
点击查看完整代码
from pyecharts.charts import Bar from pyecharts import options as opts # 你的数据 me = [165, 50, 12] idol = [178, 65, 25] items = ["身高(cm)", "体重(kg)", "年龄"] bar = Bar() bar.add_xaxis(items) bar.add_yaxis("我", me, label_opts=opts.LabelOpts(is_show=True)) bar.add_yaxis("偶像", idol, label_opts=opts.LabelOpts(is_show=True)) bar.set_global_opts( title_opts={"text": "我和偶像的对比"} ) bar.reversal_axis() bar.render("me_vs_idol.html")
15.4 折线图 - 追踪变化趋势
15.4.1 折线图的应用场景
**折线图(Line Chart)**用线段连接各个数据点,显示数据随时间或其他因素的变化趋势。
折线图适合用来:
- 显示趋势: 比如一年的气温变化
- 对比变化: 比较两个学生的成绩进步情况
- 预测未来: 根据历史数据预测趋势
生活中的折线图例子:
- 天气预报的气温曲线
- 新冠疫情的数据曲线
- 股票价格的K线图
15.4.2 创建一个简单的折线图
让我们制作一个显示一周气温变化的折线图:
from pyecharts.charts import Line
# 创建折线图
line = Line()
# 添加x轴数据(星期)
line.add_xaxis(["周一", "周二", "周三", "周四", "周五", "周六", "周日"])
# 添加y轴数据(最高气温)
line.add_yaxis("最高气温(°C)", [22, 24, 26, 25, 23, 28, 30])
# 设置标题
line.set_global_opts(title_opts={"text": "一周气温变化"})
# 生成图表
line.render("temperature_line.html")
图表解读:
- x轴表示星期
- y轴表示温度
- 折线显示温度的变化趋势
- 可以看出哪天最热,哪天最凉快
15.4.3 添加多个数据系列
折线图特别适合对比多个数据系列的变化趋势:
from pyecharts.charts import Line
line = Line()
# 添加x轴
line.add_xaxis(["周一", "周二", "周三", "周四", "周五", "周六", "周日"])
# 添加多组数据
line.add_yaxis("最高气温(°C)", [22, 24, 26, 25, 23, 28, 30])
line.add_yaxis("最低气温(°C)", [15, 16, 18, 17, 14, 19, 20])
# 设置标题
line.set_global_opts(title_opts={"text": "一周气温变化"})
# 生成图表
line.render("temperature_double_line.html")
图表解读:
- 两条折线分别代表最高气温和最低气温
- 可以看出每天的温差(两条线之间的距离)
- 可以看出气温的总体变化趋势
给家长的小贴士
- 趋势解读: 教孩子如何从折线图中读取信息(上升、下降、波动)
- 数据对比: 多条折线对比时,引导孩子找出规律(如:A一直比B高,A和B呈相反变化)
- 实际应用: 鼓励孩子记录自己的数据(如每天的学习时间),用折线图分析
- 数据收集: 这个过程还能培养孩子的数据收集习惯
实践练习4:我的成绩进步曲线
任务: 制作一个折线图,显示你最近5次考试的成绩变化:
- x轴: 第1次、第2次、第3次、第4次、第5次
- y轴: 语文和数学的成绩
- 添加数据标记点
示例数据:
chinese = [75, 78, 82, 85, 88] math = [80, 79, 83, 87, 90] exams = ["第1次", "第2次", "第3次", "第4次", "第5次"]答案:
点击查看完整代码
from pyecharts.charts import Line from pyecharts import options as opts # 成绩数据 chinese = [75, 78, 82, 85, 88] math = [80, 79, 83, 87, 90] exams = ["第1次", "第2次", "第3次", "第4次", "第5次"] line = Line() line.add_xaxis(exams) line.add_yaxis( "语文", chinese, markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]), markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]) ) line.add_yaxis("数学", math) line.set_global_opts( title_opts={"text": "我的成绩进步曲线"}, yaxis_opts=opts.AxisOpts(name="分数"), xaxis_opts=opts.AxisOpts(name="考试次数") ) line.render("my_scores.html")运行后,你会看到两条折线,语文的最高分会自动标记,平均分也会显示!
15.4.4 平滑曲线和面积图
1. 平滑曲线
默认的折线图是直线连接各个点。设置is_smooth=True可以让线条变得平滑:
from pyecharts.charts import Line
line = Line()
line.add_xaxis(["1月", "2月", "3月", "4月", "5月", "6月"])
line.add_yaxis("销售额(万元)", [10, 15, 13, 18, 20, 25], is_smooth=True)
line.set_global_opts(title_opts={"text": "上半年销售额"})
line.render("smooth_line.html")
效果: 折线变成了平滑的曲线,看起来更美观,适合表示连续变化的数据(如气温、速度等)。
2. 面积图
面积图是在折线图下方填充颜色,强调数据的“量“:
from pyecharts.charts import Line
from pyecharts import options as opts
line = Line()
line.add_xaxis(["周一", "周二", "周三", "周四", "周五", "周六", "周日"])
line.add_yaxis(
"学习时间(小时)",
[2, 2.5, 3, 2, 3.5, 4, 3],
areastyle_opts=opts.AreaStyleOpts(opacity=0.5) # 填充区域,透明度0.5
)
line.set_global_opts(title_opts={"text": "一周学习时间统计"})
line.render("area_line.html")
使用场景: 面积图适合强调累积量或总量,如每天的学习时间、每月的零花钱支出。
给家长的小贴士
- 平滑 vs 直线: 平滑曲线看起来更美观,但不适合强调精确的数据点
- 面积图: 适合用“积木堆叠“或“装水“的类比解释
- 透明度: opacity范围是0到1,0表示完全透明,1表示不透明
- 交互功能: 鼠标悬停在图表上时,会显示详细的数据提示框
15.4.5 折线图的标记功能
pyecharts可以在折线图上自动标记特殊点:
from pyecharts.charts import Line
from pyecharts import options as opts
line = Line()
line.add_xaxis(["1月", "2月", "3月", "4月", "5月", "6月"])
line.add_yaxis(
"销售额(万元)",
[10, 15, 13, 18, 20, 25],
# 标记点:最大值、最小值
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最大值"),
opts.MarkPointItem(type_="min", name="最小值")
]
),
# 标记线:平均值
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(type_="average", name="平均值")
]
)
)
line.set_global_opts(title_opts={"text": "上半年销售额"})
line.render("marked_line.html")
标记说明:
- 标记点: 用圆点标记特殊位置(最大值、最小值、自定义点)
- 标记线: 用直线标记特殊位置(平均值、自定义线)
实践练习5:游戏等级提升记录
任务: 假设你在一周内玩游戏,每天记录等级提升:
- x轴: 周一到周日
- y轴: 等级(假设起始等级1,每天提升不同)
- 要求:标记最大提升的那一天,显示平均等级
示例数据:
levels = [1, 3, 5, 8, 10, 15, 18] gains = [0, 2, 2, 3, 2, 5, 3] # 每天提升的等级答案:
点击查看完整代码
from pyecharts.charts import Line from pyecharts import options as opts levels = [1, 3, 5, 8, 10, 15, 18] days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] line = Line() line.add_xaxis(days) line.add_yaxis( "等级", levels, markpoint_opts=opts.MarkPointOpts( data=[ opts.MarkPointItem(type_="max", name="最高等级"), opts.MarkPointItem(type_="min", name="最低等级") ] ), markline_opts=opts.MarkLineOpts( data=[ opts.MarkLineItem(type_="average", name="平均等级") ] ) ) line.set_global_opts( title_opts={"text": "游戏等级提升记录"}, yaxis_opts=opts.AxisOpts(name="等级"), xaxis_opts=opts.AxisOpts(name="日期") ) line.render("game_levels.html")
15.5 饼图 - 显示比例关系
15.5.1 饼图的应用场景
**饼图(Pie Chart)**用圆形的扇形大小表示各部分占整体的比例。
饼图适合用来:
- 显示占比: 班级男女生比例
- 分配关系: 零花钱的用途分配
- 组成结构: 家庭支出中各项费用的占比
生活中的饼图例子:
- 预算分配图
- 选举结果占比
- 手机存储空间使用情况
重要: 饼图的数据加起来应该是100%(或1),表示一个整体。
15.5.2 创建一个简单的饼图
让我们制作一个显示班级运动爱好的饼图:
from pyecharts.charts import Pie
# 数据
sports = ["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"]
counts = [15, 12, 8, 10, 6, 9]
# 创建饼图
pie = Pie()
# 添加数据
pie.add("", list(zip(sports, counts)))
# 设置标题
pie.set_global_opts(title_opts={"text": "班级运动喜好分布"})
# 生成图表
pie.render("sports_pie.html")
代码解析:
list(zip(sports, counts))将两个列表合并成:[("篮球", 15), ("足球", 12), ...]- 饼图的
add()方法的第一个参数是系列名称(可以为空字符串)
15.5.3 饼图的样式设置
1. 显示百分比和标签
默认情况下,饼图会显示类别名称。我们可以同时显示百分比:
from pyecharts.charts import Pie
from pyecharts import options as opts
sports = ["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"]
counts = [15, 12, 8, 10, 6, 9]
pie = Pie()
pie.add(
"",
list(zip(sports, counts)),
label_opts=opts.LabelOpts(formatter="{b}: {d}%") # {b}=名称, {d}=百分比
)
pie.set_global_opts(title_opts={"text": "班级运动喜好分布"})
pie.render("sports_pie_percent.html")
formatter参数说明:
{a}: 系列名称{b}: 数据项名称(如“篮球“){c}: 数值(如15){d}: 百分比(如18.07%)
2. 环形饼图
环形饼图比普通饼图更美观,中间是空心的:
from pyecharts.charts import Pie
from pyecharts import options as opts
sports = ["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"]
counts = [15, 12, 8, 10, 6, 9]
pie = Pie()
pie.add(
"",
list(zip(sports, counts)),
radius=["30%", "70%"] # 内圆半径30%,外圆半径70%
)
pie.set_global_opts(title_opts={"text": "班级运动喜好分布"})
pie.render("donut_pie.html")
radius参数:
- 第一个值: 内圆半径
- 第二个值: 外圆半径
- 两个值越接近,环形越细
给家长的小贴士
- 百分比概念: 饼图是帮助孩子理解百分比的绝佳工具
- 数据归一化: 如果数据加起来不是100%,pyecharts会自动计算百分比
- 颜色识别: 教孩子如何从饼图的颜色和面积大小直观地理解比例
- 环形 vs 实心: 环形饼图可以在中间显示总数或标题,更美观
实践练习6:我的零花钱花哪里了
任务: 制作一个饼图,显示你一个月零花钱的使用情况:
- 类别: 零食、文具、玩具、游戏、其他
- 数据: 自己设定一个合理的分配(如: 30%, 20%, 15%, 25%, 10%)
- 要求:使用环形饼图,显示百分比
示例数据:
items = ["零食", "文具", "玩具", "游戏", "其他"] money = [60, 40, 30, 50, 20] # 单位:元答案:
点击查看完整代码
from pyecharts.charts import Pie from pyecharts import options as opts items = ["零食", "文具", "玩具", "游戏", "其他"] money = [60, 40, 30, 50, 20] pie = Pie() pie.add( "", list(zip(items, money)), radius=["35%", "65%"], # 环形 label_opts=opts.LabelOpts(formatter="{b}: {c}元 ({d}%)") ) pie.set_global_opts( title_opts={"text": "我的零花钱使用情况"}, legend_opts=opts.LegendOpts(orient="vertical", pos_left="left") ) pie.render("allowance_spending.html")运行后,你会看到一个漂亮的环形饼图,每个部分显示金额和百分比!
15.5.4 饼图的Rose图
Rose图(玫瑰图)是饼图的变体,扇形的半径不同:
from pyecharts.charts import Pie
from pyecharts import options as opts
sports = ["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"]
counts = [15, 12, 8, 10, 6, 9]
pie = Pie()
pie.add(
"",
list(zip(sports, counts)),
radius="60%", # 半径
rosetype="radius" # 设置为玫瑰图
)
pie.set_global_opts(title_opts={"text": "班级运动喜好分布(Rose图)"})
pie.render("rose_pie.html")
Rose图特点:
- 每个扇形的半径不同,数据越大,扇形越大
- 适合数据差异较大的情况
- 视觉效果更丰富
给家长的小贴士
- Rose图 vs 饼图: Rose图强调数值差异,饼图强调比例关系
- 选择建议: 数据差异大时用Rose图,数据相近时用普通饼图
- 交互功能: 点击某个扇形,该扇形会突出显示
15.5.5 饼图的嵌套
饼图可以嵌套,显示多层数据:
from pyecharts.charts import Pie
from pyecharts import options as opts
# 内圈数据
inner_data = [("电子产品", 60), ("服装", 30), ("食品", 50)]
# 外圈数据(细分)
outer_data = [
("手机", 30), ("电脑", 20), ("耳机", 10),
("男装", 15), ("女装", 15),
("零食", 25), ("饮料", 15), ("水果", 10)
]
pie = Pie()
# 添加内圈
pie.add(
"",
inner_data,
radius=["0%", "35%"], # 从中心到35%的区域
label_opts=opts.LabelOpts(formatter="{b}: {d}%")
)
# 添加外圈
pie.add(
"",
outer_data,
radius=["45%", "70%"], # 从45%到70%的区域
label_opts=opts.LabelOpts(formatter="{b}: {d}%")
)
pie.set_global_opts(title_opts={"text": "销售额分布(嵌套饼图)"})
pie.render("nested_pie.html")
使用场景: 嵌套饼图适合显示“大类-小类“的层级关系,如“运动-球类、跑步、游泳“。
实践练习7:我的时间分配
任务: 制作一个嵌套饼图,显示你一天的时间分配:
内圈(大类):
- 睡眠: 9小时
- 上学: 8小时
- 作业: 3小时
- 娱乐: 4小时
外圈(娱乐细分):
- 看电视: 1.5小时
- 玩游戏: 1小时
- 运动: 1小时
- 其他: 0.5小时
答案:
点击查看完整代码
from pyecharts.charts import Pie from pyecharts import options as opts # 内圈: 大类 inner_data = [ ("睡眠", 9), ("上学", 8), ("作业", 3), ("娱乐", 4) ] # 外圈: 娱乐细分 outer_data = [ ("看电视", 1.5), ("玩游戏", 1), ("运动", 1), ("其他", 0.5), # 补充其他类别的数据(为了图形完整) ("睡眠细分", 9), ("上学细分", 8), ("作业细分", 3) ] pie = Pie() pie.add( "", inner_data, radius=["0%", "35%"], label_opts=opts.LabelOpts(formatter="{b}: {c}小时") ) pie.add( "", outer_data, radius=["45%", "70%"], label_opts=opts.LabelOpts(formatter="{b}: {c}小时") ) pie.set_global_opts(title_opts={"text": "我的一天时间分配"}) pie.render("my_day_pie.html")提示: 这个例子展示了嵌套饼图的应用,但外圈数据不完全对称,实际情况中可能需要更完整的数据分类。
15.6 综合项目:制作班级成绩分析报告
现在我们已经学会了柱状图、折线图、饼图,让我们做一个综合项目:班级成绩分析报告系统。
这个项目会综合运用我们学到的所有知识!
15.6.1 项目需求
假设你是班长,老师给你一份班级成绩数据,你需要:
- 用柱状图显示每个学生的总分排名
- 用折线图显示班级平均分的变化趋势
- 用饼图显示各分数段的人数分布
- 生成一个完整的HTML报告
原始数据:
| 姓名 | 语文 | 数学 | 英语 | 物理 | 化学 |
|---|---|---|---|---|---|
| 小明 | 85 | 92 | 78 | 88 | 90 |
| 小红 | 90 | 88 | 95 | 92 | 94 |
| 小刚 | 78 | 85 | 82 | 80 | 83 |
| 小丽 | 92 | 95 | 88 | 90 | 91 |
| 小华 | 88 | 90 | 91 | 85 | 89 |
| 小强 | 80 | 82 | 85 | 78 | 80 |
| 小芳 | 95 | 90 | 92 | 95 | 93 |
15.6.2 项目实现
让我们一步步完成这个项目:
步骤1: 准备数据
# 学生姓名
students = ["小明", "小红", "小刚", "小丽", "小华", "小强", "小芳"]
# 各科成绩
chinese = [85, 90, 78, 92, 88, 80, 95]
math = [92, 88, 85, 95, 90, 82, 90]
english = [78, 95, 82, 88, 91, 85, 92]
physics = [88, 92, 80, 90, 85, 78, 95]
chemistry = [90, 94, 83, 91, 89, 80, 93]
# 计算总分
total_scores = []
for i in range(len(students)):
total = chinese[i] + math[i] + english[i] + physics[i] + chemistry[i]
total_scores.append(total)
print("总分:", total_scores)
运行结果:
总分: [433, 459, 408, 456, 443, 405, 465]
步骤2: 柱状图 - 总分排名
from pyecharts.charts import Bar
from pyecharts import options as opts
# 创建柱状图
bar = Bar()
# 添加数据
bar.add_xaxis(students)
bar.add_yaxis(
"总分",
total_scores,
label_opts=opts.LabelOpts(is_show=True) # 显示数值
)
# 设置全局选项
bar.set_global_opts(
title_opts={"text": "班级总分排名"},
yaxis_opts=opts.AxisOpts(name="分数"),
xaxis_opts=opts.AxisOpts(name="学生"),
toolbox_opts=opts.ToolboxOpts(is_show=True) # 显示工具栏
)
# 生成图表
bar.render("class_ranking.html")
步骤3: 折线图 - 科目平均分
from pyecharts.charts import Line
# 计算各科平均分
chinese_avg = sum(chinese) // len(chinese)
math_avg = sum(math) // len(math)
english_avg = sum(english) // len(english)
physics_avg = sum(physics) // len(physics)
chemistry_avg = sum(chemistry) // len(chemistry)
subjects = ["语文", "数学", "英语", "物理", "化学"]
avg_scores = [chinese_avg, math_avg, english_avg, physics_avg, chemistry_avg]
# 创建折线图
line = Line()
line.add_xaxis(subjects)
line.add_yaxis(
"平均分",
avg_scores,
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最高分"),
opts.MarkPointItem(type_="min", name="最低分")
]
)
)
line.set_global_opts(
title_opts={"text": "各科目平均分"},
yaxis_opts=opts.AxisOpts(name="分数"),
xaxis_opts=opts.AxisOpts(name="科目")
)
line.render("subject_averages.html")
步骤4: 饼图 - 分数段分布
from pyecharts.charts import Pie
# 统计分数段
ranges = ["优秀(90分以上)", "良好(80-89)", "及格(60-79)", "不及格(60分以下)"]
counts = [0, 0, 0, 0]
# 统计总分段
for score in total_scores:
avg = score / 5 # 计算平均分
if avg >= 90:
counts[0] += 1
elif avg >= 80:
counts[1] += 1
elif avg >= 60:
counts[2] += 1
else:
counts[3] += 1
print("分数段分布:", counts)
# 创建饼图
pie = Pie()
pie.add(
"",
list(zip(ranges, counts)),
radius=["30%", "60%"],
label_opts=opts.LabelOpts(formatter="{b}: {c}人 ({d}%)")
)
pie.set_global_opts(title_opts={"text": "班级成绩分布"})
pie.render("score_distribution.html")
运行结果:
分数段分布: [3, 3, 1, 0] # 优秀3人,良好3人,及格1人,不及格0人
步骤5: 组合所有图表
pyecharts提供了一个Page类,可以把多个图表组合在一个HTML页面:
from pyecharts.charts import Bar, Line, Pie
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
# 数据准备(省略,参考上面的代码)
# 创建三个图表(代码省略)
bar = Bar()
# ... 添加数据和选项
line = Line()
# ... 添加数据和选项
pie = Pie()
# ... 添加数据和选项
# 组合图表
from pyecharts.charts import Page
page = Page(layout=Page.SimplePageLayout)
page.add(
bar,
line,
pie
)
page.render("class_report.html")
运行结果: 打开class_report.html,你会看到三个图表从上到下排列在一个页面中,形成一个完整的成绩分析报告!
给家长的小贴士
- 项目式学习: 这个综合项目能培养孩子的整体思维和问题解决能力
- 数据收集: 鼓励孩子用真实数据(如自己班级的成绩)替换示例数据
- 分析能力: 让孩子根据图表分析班级情况(如:哪科最难,谁进步最大)
- 逐步完成: 强调分步骤完成,不要试图一次写完所有代码
- 调试技巧: 如果某个图表有问题,单独运行它的代码,找出错误
综合练习8:完整的数据分析报告
任务: 选择一个你感兴趣的主题,制作一个完整的数据分析报告:
主题建议:
- 运动数据分析: 班级同学最喜欢的运动类型
- 游戏数据分析: 你和朋友的游戏等级、胜率、场次对比
- 零花钱分析: 一个月的零花钱来源和用途
- 阅读分析: 这学期读了多少本书,各类书的比例
- 自定义主题: 其他你感兴趣的数据
要求:
- 至少包含3种图表(柱状图、折线图、饼图)
- 每个图表都要有标题和坐标轴说明
- 用Page组合所有图表
- 根据图表写出3条分析结论
示例代码框架:
点击查看代码框架
from pyecharts.charts import Bar, Line, Pie from pyecharts.charts import Page from pyecharts import options as opts # 步骤1: 准备数据 # TODO: 填写你的数据 # 步骤2: 创建柱状图 bar = Bar() # TODO: 添加数据和选项 # 步骤3: 创建折线图 line = Line() # TODO: 添加数据和选项 # 步骤4: 创建饼图 pie = Pie() # TODO: 添加数据和选项 # 步骤5: 组合所有图表 page = Page() page.add(bar, line, pie) page.render("my_report.html") print("报告已生成!")
15.7 进阶技巧:让图表更美观
15.7.1 使用主题
pyecharts提供了多种预设主题,可以快速改变图表的配色:
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
# 使用DARK主题
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK))
bar.add_xaxis(["苹果", "香蕉", "橙子", "草莓", "葡萄"])
bar.add_yaxis("价格", [8, 3, 6, 15, 12])
bar.set_global_opts(title_opts={"text": "水果价格表"})
bar.render("themed_chart.html")
可用主题:
ThemeType.LIGHT: 浅色主题(默认)ThemeType.DARK: 深色主题ThemeType.ROMA: 罗马主题ThemeType.SHINE: 闪亮主题ThemeType.VINTAGE: 复古主题
15.7.2 自定义颜色
如果你想自定义图表的颜色,可以使用颜色列表:
from pyecharts.charts import Pie
from pyecharts import options as opts
items = ["篮球", "足球", "羽毛球", "乒乓球", "跑步", "游泳"]
counts = [15, 12, 8, 10, 6, 9]
pie = Pie()
pie.add(
"",
list(zip(items, counts)),
# 自定义颜色
color=["#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A", "#98D8C8", "#F7DC6F"]
)
pie.set_global_opts(title_opts={"text": "班级运动喜好"})
pie.render("custom_colors.html")
颜色代码说明:
- 使用十六进制颜色码(如
#FF6B6B) - 可以在线搜索“hex color picker“选择颜色
- 颜色列表长度应该与数据项数量一致
15.7.3 添加提示框和工具栏
from pyecharts.charts import Bar
from pyecharts import options as opts
bar = Bar()
bar.add_xaxis(["第一季度", "第二季度", "第三季度", "第四季度"])
bar.add_yaxis("销售额", [120, 200, 150, 180])
bar.set_global_opts(
# 提示框配置
tooltip_opts=opts.TooltipOpts(
trigger="axis", # 坐标轴触发
axis_pointer_type="shadow" # 阴影指示器
),
# 工具栏配置
toolbox_opts=opts.ToolboxOpts(
is_show=True,
feature={
"saveAsImage": {}, # 保存为图片
"dataView": {}, # 数据视图
"restore": {} # 还原
}
),
# 区域缩放
datazoom_opts=opts.DataZoomOpts(is_show=True)
)
bar.render("advanced_features.html")
功能说明:
- 提示框: 鼠标悬停时显示详细信息
- 工具栏: 右上角显示保存、数据视图等工具
- 区域缩放: 可以缩放查看部分数据
给家长的小贴士
- 颜色搭配: 教孩子基本的配色原则(对比色、同类色)
- 主题选择: 不同主题适合不同场合(如DARK适合夜间查看)
- 功能叠加: 不要一次添加太多功能,会影响图表的可读性
- 审美培养: 鼓励孩子尝试不同的配色,培养审美能力
15.8 常见错误和调试
15.8.1 数据类型错误
错误代码:
from pyecharts.charts import Bar
bar = Bar()
bar.add_xaxis("苹果") # 错误:应该是列表
bar.add_yaxis("价格", 8) # 错误:应该是列表
错误信息:
TypeError: Input x_axis data must be list
正确代码:
bar.add_xaxis(["苹果"]) # 使用列表
bar.add_yaxis("价格", [8]) # 使用列表
给家长的小贴士
- 列表 vs 单个值: pyecharts需要列表,即使只有一个数据也要用
[8]- 仔细阅读错误信息: 错误信息会明确告诉你是哪个参数有问题
15.8.2 数据长度不一致
错误代码:
bar.add_xaxis(["苹果", "香蕉", "橙子"])
bar.add_yaxis("价格", [8, 3]) # 只有2个数据,少了1个
错误信息:
AssertionError: x_axis data and y_axis data must be same length
解决方法: 确保x轴和y轴的数据数量一致:
bar.add_xaxis(["苹果", "香蕉", "橙子"])
bar.add_yaxis("价格", [8, 3, 6]) # 3个数据
15.8.3 文件路径错误
错误代码:
bar.render("C:\Users\用户名\桌面\chart.html")
错误信息:
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes
原因: Python中\是转义字符,\U会被认为是Unicode转义。
解决方法1: 使用原始字符串
bar.render(r"C:\Users\用户名\桌面\chart.html") # 注意r前缀
解决方法2: 使用正斜杠
bar.render("C:/Users/用户名/桌面/chart.html") # 使用/
解决方法3: 只写文件名(推荐)
bar.render("chart.html") # 保存到当前目录
给家长的小贴士
- 路径问题: 小学生可能不理解文件路径,建议让他们只写文件名
- 文件查找: 生成的HTML文件在当前工作目录,可以让孩子用文件管理器搜索
- 桌面快捷方式: 在桌面上创建一个“我的图表“文件夹,方便查找
15.8.4 HTML文件打不开或空白
问题1: HTML文件打开后是空白页
原因: 代码运行时出现错误,但没有生成完整的HTML文件。
解决方法: 在Python中运行代码时,查看是否有错误提示。常见的错误:
- 拼写错误:
add_xasis应该是add_xaxis - 缺少括号或引号
- 变量名未定义
问题2: 浏览器打不开HTML文件
原因: 浏览器太老,不支持某些特性。
解决方法: 更新浏览器或使用Chrome、Edge、Firefox等现代浏览器。
15.8.5 调试技巧
技巧1: 逐步验证
不要一次写完所有代码,而是分步测试:
# 步骤1: 测试数据
print("x轴:", ["苹果", "香蕉"])
print("y轴:", [8, 3])
# 步骤2: 测试图表创建
bar = Bar()
print("图表创建成功")
# 步骤3: 测试添加数据
bar.add_xaxis(["苹果", "香蕉"])
bar.add_yaxis("价格", [8, 3])
print("数据添加成功")
# 步骤4: 测试渲染
bar.render("test.html")
print("渲染完成")
技巧2: 简化数据
如果数据很复杂,先用简单数据测试:
# 复杂数据可能有1000条
# x_data = [...] # 1000条
# y_data = [...] # 1000条
# 先用3条数据测试
x_data = ["A", "B", "C"]
y_data = [1, 2, 3]
bar = Bar()
bar.add_xaxis(x_data)
bar.add_yaxis("测试", y_data)
bar.render("simple_test.html")
技巧3: 查看HTML源代码
如果图表显示不正常,用文本编辑器打开HTML文件,搜索"code":
<script>
var chart = echarts.init(...);
var option = {
"title": {...},
"tooltip": {...},
...
};
chart.setOption(option);
</script>
查看是否有"error"或"undefined"等异常信息。
给家长的小贴士
- 调试思维: 教孩子“分而治之“的调试方法,把大问题拆成小问题
- 错误是朋友: 强调错误信息是帮助我们解决问题的线索
- 保存中间版本: 鼓励孩子定期保存代码的备份,出错时可以回退
15.9 本章小结
15.9.1 核心知识点回顾
1. 数据可视化的重要性
- 把抽象的数字变成直观的图形
- 让数据更容易理解和分析
- 帮助发现数据背后的规律
2. pyecharts库的使用流程
安装: pip install pyecharts
↓
导入: from pyecharts.charts import Bar
↓
创建: bar = Bar()
↓
数据: bar.add_xaxis() / bar.add_yaxis()
↓
选项: bar.set_global_opts()
↓
渲染: bar.render("file.html")
3. 三种常见图表
| 图表类型 | 用途 | 适合场景 |
|---|---|---|
| 柱状图 | 比较不同类别 | 排名、对比、统计 |
| 折线图 | 显示变化趋势 | 成绩进步、气温变化、股票走势 |
| 饼图 | 显示比例关系 | 费用分配、偏好分布、成分构成 |
4. 图表的配置选项
- 标题: title_opts
- 坐标轴: xaxis_opts / yaxis_opts
- 标签: label_opts
- 图例: legend_opts
- 工具栏: toolbox_opts
- 提示框: tooltip_opts
5. 高级功能
- 多系列: 在一个图表上显示多组数据
- 堆叠: 堆叠柱状图显示部分与整体
- 嵌套: 嵌套饼图显示层级关系
- 组合: 用Page组合多个图表
15.9.2 能力检查表
请孩子自我检查以下技能是否掌握:
- 能独立安装pyecharts库
- 能创建并保存一个简单的柱状图
- 能创建并保存一个简单的折线图
- 能创建并保存一个简单的饼图
- 能为图表添加标题和坐标轴说明
- 能在一个图表上显示多组数据
- 能使用Page组合多个图表
- 能读懂简单的错误信息并调试
- 能独立完成一个数据分析小项目
15.9.3 常见问题快速参考
| 问题 | 解决方法 |
|---|---|
| 安装失败 | 使用国内镜像源:pip install pyecharts -i https://pypi.tuna.tsinghua.edu.cn/simple |
| 中文乱码 | 在文件第一行添加# -*- coding: utf-8 -*- |
| 数据长度不一致 | 检查x轴和y轴的数据数量是否相同 |
| HTML文件找不到 | 只写文件名(如chart.html),保存到当前目录 |
| 图表空白 | 检查浏览器,使用Chrome或Edge等现代浏览器 |
15.10 挑战练习
挑战1: 天气数据分析
任务: 从网上查找你所在城市最近一周的天气数据(最高气温、最低气温、天气状况),制作:
- 折线图:显示气温变化
- 饼图:显示不同天气状况的比例(如:晴天3天,阴天2天,雨天2天)
要求:
- 使用真实数据
- 图表有标题和说明
- 添加数据标记点(最高温、最低温)
挑战2: 我的学习时间统计
任务: 记录自己一周每天的学习时间,制作:
- 柱状图:显示每天的学习时长
- 饼图:显示学习时间的分配(如:周一2小时,周二3小时…)
要求:
- 数据真实可靠
- 分析哪天学习时间最长/最短
- 找出学习规律并给出建议
挑战3: 游戏数据分析
任务: 如果你有喜欢的游戏,记录游戏数据,制作:
- 柱状图:你和朋友的等级对比
- 折线图:最近10次的胜率变化
- 饼图:使用英雄/武器的频率
要求:
- 至少包含3种图表
- 用Page组合所有图表
- 写出分析结论(如:我最擅长哪个英雄)
挑战4: 班级调查报告
任务: 设计一个班级调查(如:最喜欢的科目、最喜欢的运动、每天的学习时间…),收集数据后制作完整的分析报告。
要求:
- 调查至少10名同学
- 使用柱状图、折线图、饼图
- 报告包含:
- 调查主题
- 数据来源
- 图表分析
- 你的建议
挑战5: 创意数据可视化
任务: 选择一个你感兴趣的主题(如:我的阅读记录、零花钱追踪、运动数据分析…),制作一个创意数据可视化项目。
要求:
- 数据真实且有连续性(至少记录一周)
- 至少3个图表
- 尝试使用主题、自定义颜色等高级功能
- 向同学展示你的报告,并收集反馈
15.11 下一步预告
恭喜你完成了第15章的学习!你已经掌握了:
- ✅ 数据可视化的基本概念
- ✅ 柱状图、折线图、饼图的制作
- ✅ pyecharts库的使用方法
- ✅ 完整的数据分析报告制作
在第16章:图形程序中,你将学习:
- 使用tkinter库创建图形界面
- 按钮、文本框、标签等控件
- 制作带界面的交互程序
想象一下,不再是在黑色的命令行窗口输入命令,而是有漂亮的窗口、按钮、输入框…这就是图形界面的魅力!我们下一章见!
附录:pyecharts速查表
常用图表类
from pyecharts.charts import Bar, Line, Pie
# 柱状图
bar = Bar()
bar.add_xaxis(x_data)
bar.add_yaxis(series_name, y_data)
bar.render("bar.html")
# 折线图
line = Line()
line.add_xaxis(x_data)
line.add_yaxis(series_name, y_data)
line.render("line.html")
# 饼图
pie = Pie()
pie.add(series_name, data)
pie.render("pie.html")
常用配置选项
from pyecharts import options as opts
# 标题
title_opts={"text": "图表标题"}
# 坐标轴
xaxis_opts=opts.AxisOpts(name="x轴名称")
yaxis_opts=opts.AxisOpts(name="y轴名称")
# 标签
label_opts=opts.LabelOpts(is_show=True) # 显示数据标签
# 提示框
tooltip_opts=opts.TooltipOpts(trigger="axis")
# 工具栏
toolbox_opts=opts.ToolboxOpts(is_show=True)
# 数据缩放
datazoom_opts=opts.DataZoomOpts(is_show=True)
常用主题
from pyecharts.globals import ThemeType
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK))
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.ROMA))
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.SHINE))
Page组合图表
from pyecharts.charts import Page
page = Page()
page.add(chart1, chart2, chart3)
page.render("combined.html")
祝贺你完成第15章的学习! 🎉
现在,你已经能用Python制作专业的数据报表了!试试用你学到的技能,记录和分析生活中的数据吧!