《python编程从入门到实践》15 生成数据

📘 第15章 教程:生成数据
数据可视化是指通过可视化表示来探索数据。Python提供了多个强大的可视化库,本章将使用Matplotlib和Plotly来实现不同形式的图表。
常用参数及讲解:
一、 Matplotlib 常用方法与参数
1. 折线图 plot()
x,y:必要参数,分别代表横纵坐标的数据序列。linewidth(或lw):线条粗细。例如linewidth=2使线条更醒目(对应15.2.1)。color:线条颜色。支持颜色名称(如'red')、缩写(如'r')或十六进制码。label:图例标签。配合ax.legend()使用,用于区分多条线。marker:数据点标记样式。如marker='o'(圆圈)、marker='s'(方块)。markersize(或ms):数据点标记的大小。
2. 散点图 scatter()
x,y:横纵坐标数据。s:数据点的尺寸(size)。可传入单个数值统一设置,也可传入列表逐点设置大小。c:数据点的颜色。可传入单一颜色名;若要实现颜色渐变,可传入一个数值列表,此时需配合cmap使用(对应15.2.9)。cmap:颜色映射。仅当c为数值序列时生效,将数值映射到色谱。常用值如'Reds','Blues','viridis','plasma'等。edgecolors:数据点边缘的颜色,常设为'none'以消除边缘让散点更柔和。alpha:透明度。取值 0.0(全透明)到 1.0(不透明),在密集散点图中非常有用,可凸显数据聚集区域。
3. 样式与刻度定制方法
plt.style.use('stylename'):全局样式设置。常用内置样式如'seaborn','ggplot','bmh'等,可直接改变图表整体美感(对应15.2.3)。ax.set_title("Title", fontsize=14):设置图表标题及字体大小。ax.set_xlabel("X_Label", fontsize=14)/ax.set_ylabel(...):设置坐标轴标签及字体大小。ax.tick_params(axis='both', labelsize=12):定制刻度标记。axis指定作用于哪个轴('x','y'或'both'),labelsize设置刻度字号。ax.set_xticks([list]):设置 x 轴刻度的位置(传入数值列表)。ax.set_xticklabels([list], rotation=45):设置 x 轴刻度的文本标签,rotation用于旋转角度防重叠(对应15.2.7 及日期图)。ax.axis([xmin, xmax, ymin, ymax]):校正绘图。直接设定坐标轴的起止范围;若传入False或'off'则隐藏坐标轴(对应15.2.2)。
4. 其他方法
plt.savefig('filename.png', bbox_inches='tight'):自动保存绘图。bbox_inches='tight'是极常用的参数,用于裁剪图表周围多余的空白区域(对应15.2.10)。
二、 Plotly Express 常用方法与参数
(第3版全面采用 Plotly Express 模块,导入方式通常为 import plotly.express as px)
1. 直方图 px.histogram()
用于掷骰子项目的结果分布可视化:
data_frame:传入的数据源,通常为 Pandas DataFrame 或字典。x:指定作为 x 轴的数据列名或数据列表(如掷骰子的结果)。y:指定 y 轴数据。若省略,默认统计 x 轴各值出现的频次。nbins:直方图的柱子数量。调整此参数可控制分布的精细度。histnorm:归一化模式。如设为'percent'可显示百分比而非绝对频数。barmode:多组数据时的排列模式。如'group'(并排显示)或'overlay'(重叠显示,需配合透明度opacity)。
2. 柱状图/条形图 px.bar()
x,y:横纵坐标数据。color:分组/颜色区分参数。传入分类字段名,自动按类别着色并生成图例。barmode:同上,'group'并排,'relative'堆叠。
3. 图表更新与定制方法
Plotly Express 生成的 fig 对象可通过 .update_ 系列方法深度定制:
fig.update_layout(title_text="My Title", xaxis_title="X", yaxis_title="Y")title_text:图表主标题。xaxis_title/yaxis_title:坐标轴标题(PX 默认可能不显轴标题,需手动开启)。
fig.update_traces(opacity=0.75, marker_line_width=1, marker_line_color='white')opacity:透明度,0-1之间,在重叠柱状图(如同时掷两个骰子)中极为关键。marker_line_width/marker_line_color:柱子边框的宽度和颜色,增加边框能让各柱体区分更明显。
4. 保存方法
fig.write_html("filename.html"):保存图形。Plotly 保留交互特性的标准保存方式,可在浏览器中打开查看悬停、缩放等交互效果(对应15.4.10)。
15.1 安装 Matplotlib
Matplotlib 是一个数学绘图库,可制作简单的图表(如折线图、散点图)。使用 pip 安装它:
python -m pip install --user matplotlib
[notice] A new release of pip is available: 26.0.1 -> 26.1
[notice] To update, run: python.exe -m pip install --upgrade pip
E:\C sharp电子书\电子书\python\python学习>python -m pip install --user matplotlib
Requirement already satisfied: matplotlib in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (3.10.7)
Requirement already satisfied: contourpy>=1.0.1 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (1.3.3)
Requirement already satisfied: cycler>=0.10 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (4.61.0)
Requirement already satisfied: kiwisolver>=1.3.1 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (1.4.9)
Requirement already satisfied: numpy>=1.23 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (2.3.5)
Requirement already satisfied: packaging>=20.0 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (25.0)
Collecting pillow>=8 (from matplotlib)
Downloading pillow-12.2.0-cp312-cp312-win_amd64.whl.metadata (9.0 kB)
Requirement already satisfied: pyparsing>=3 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (3.2.5)
Requirement already satisfied: python-dateutil>=2.7 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from matplotlib) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages (from python-dateutil>=2.7->matplotlib) (1.17.0)
Downloading pillow-12.2.0-cp312-cp312-win_amd64.whl (7.1 MB)
━━╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.5/7.1 MB 36.6 kB/s eta 0:03:00
15.2 绘制简单的折线图
15.2.1 使用 Matplotlib 绘制折线图
def plot(
*args: ArrayLike | float, # 位置参数:数据
scalex: bool = True, # 自动缩放X轴
scaley: bool = True, # 自动缩放Y轴
data: Any | None = None, # 数据源
**kwargs: Any # 关键字参数:样式属性
) -> list[Line2D] # 返回 Line2D 对象列表
# 示例
plt.plot([1, 2, 3, 4, 5]) # Y值,X自动为 0-4
plt.plot([1, 2, 3], [1, 4, 9]) # X和Y
plt.plot([1, 2, 3], [1, 4, 9], 'b--') # 蓝色虚线
下面绘制一个简单的折线图,其中包含几个平方数:
import matplotlib.pyplot as plt
squares = [1, 4, 9, 16, 25]
plt.plot(squares)
plt.show()
这个程序将 squares 列表传递给 plot() 函数,再调用 show() 打开Matplotlib查看器并显示图表。
15.2.2 修改标签文字和线型
你可以为图表添加标题、标签,并自定义线条样式:
squares = [1, 4, 9, 16, 25] # 定义数据列表:1-5的平方数
fig, ax = plt.subplots() # 创建图形画布(fig)和坐标轴(ax)对象
ax.plot(squares, linewidth=3) # 在坐标轴上绘制折线图,设置线宽为3
# 设置图题并给坐标轴加上标签
ax.set_title("Square Numbers", fontsize=24) # 设置图表标题,字体大小为24
ax.set_xlabel("Value", fontsize=14) # 设置X轴标签为"Value",字体大小为14
ax.set_ylabel("Square of Value", fontsize=14) # 设置Y轴标签为"Square of Value",字体大小为14
# 设置刻度标记的样式
ax.tick_params(axis='both', labelsize=14) # 设置X轴和Y轴的刻度标签字体大小为14
plt.show() # 显示绘制的图表
注意:要纠正之前图表的形状错误(曲线起点不对),需要给
plot()同时提供输入值和输出值。
15.2.3 内置样式
Matplotlib 提供了很多已定义好的样式,这些样式包含默认的背景色、网格线、线条粗细、字体、字号等设置,让你无须做太多定制就能生成引人瞩目的可视化效果。要看到能在你的系统中使用的所有样式,可在终端会话中执行如下命令:
>>> import matplotlib.pyplot as plt
>>> plt.style.available
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'petroff10', 'seaborn-v0_8', 'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark', 'seaborn-v0_8-dark-palette', 'seaborn-v0_8-darkgrid', 'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook', 'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster', 'seaborn-v0_8-talk', 'seaborn-v0_8-ticks', 'seaborn-v0_8-white', 'seaborn-v0_8-whitegrid', 'tableau-colorblind10']
15.3 绘制散点图
def scatter(
self,
x, y, # 必需:X和Y坐标数据
s=None, # 点的大小(size)
c=None, # 点的颜色(color)
marker=None, # 标记形状
cmap=None, # 颜色映射(colormap)
norm=None, # 颜色归一化
vmin=None, vmax=None, # 颜色范围的最小/最大值
alpha=None, # 透明度
linewidths=None, # 标记边框线宽
*, # 关键字参数分隔符(之后必须用关键字传参)
edgecolors=None, # 标记边框颜色
colorizer=None, # 颜色处理器(新功能)
plotnonfinite=False, # 是否绘制非有限值(NaN/Inf)
**kwargs # 其他关键字参数
):
15.3.1 使用 scatter() 绘制单个点
使用 scatter() 函数绘制单个点并设置其样式:
import matplotlib.pyplot as plt
plt.scatter(2, 4, s=200)
# 设置图表标题并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)
plt.show()
15.3.2 使用 scatter() 绘制一系列点
要绘制一系列点,可将x值和y值分别放在列表中传递给scatter():
import matplotlib.pyplot as plt
x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
plt.scatter(x_values, y_values, s=100)
plt.show()
15.3.3 自动计算数据
使用循环自动生成数据,例如计算前1000个整数的平方:
import matplotlib.pyplot as plt
x_values = range(1, 1001)
y_values = [x**2 for x in x_values]
plt.scatter(x_values, y_values, s=40)
# 设置图表标题并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置每个坐标轴的取值范围
plt.axis([0, 1100, 0, 1100000])
plt.show()

1e6 ↑
1.0 ┤
0.8 ┤
0.6 ┤
0.4 ┤
0.2 ┤
0.0 ┤
1e6 = 1 × 10⁶ = 1,000,000
2e6 = 2 × 10⁶ = 2,000,000
1.5e6 = 1.5 × 10⁶ = 1,500,000
15.3.4 删除数据点的轮廓
scatter() 默认绘制蓝色点和黑色轮廓。可以修改参数 edgecolor='none' 来删除轮廓:
plt.scatter(x_values, y_values, edgecolor='none', s=40)

15.3.5 自定义颜色
向 scatter() 传递参数 c,可设置颜色名称(如 'red')或RGB元组(取值在0~1之间):
plt.scatter(x_values, y_values, c='red', edgecolor='none', s=40)
# 或使用RGB颜色
plt.scatter(x_values, y_values, c=(0, 0.8, 0), edgecolor='none', s=40)
15.3.6 使用颜色映射
颜色映射(colormap)是一系列渐变颜色,可根据数据点的值来设置颜色。参数 c 传入y值列表,参数 cmap 指定映射名称:
plt.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, edgecolor='none', s=40)
15.3.7 自动保存图表
如果要让程序自动将图表保存到文件中,而非在查看器中显示,可调用 savefig() 替换 show():
plt.savefig('squares_plot.png', bbox_inches='tight')
# 第一个参数是文件名(可指定路径),第二个参数`bbox_inches='tight'`可裁剪图表多余的空白区域
15.4 随机漫步
随机漫步是从原点开始、每一步方向完全随机的一种路径。使用Python和Matplotlib可轻松模拟。
15.4.1 创建 RandomWalk 类
from random import choice
class RandomWalk:
"""一个生成随机漫步数据的类"""
def __init__(self, num_points=5000):
"""初始化随机漫步的属性"""
self.num_points = num_points
# 所有随机漫步都始于(0, 0)
self.x_values =
self.y_values =
def fill_walk(self):
"""计算随机漫步包含的所有点"""
# 不断漫步,直到列表达到指定的长度
while len(self.x_values) < self.num_points:
# 决定前进方向以及沿这个方向前进的距离
x_direction = choice([1, -1])
x_distance = choice([0, 1, 2, 3, 4])
x_step = x_direction * x_distance
y_direction = choice([1, -1])
y_distance = choice([0, 1, 2, 3, 4])
y_step = y_direction * y_distance
# 拒绝原地踏步
if x_step == 0 and y_step == 0:
continue
# 计算下一个点的x和y值
x = self.x_values[-1] + x_step
y = self.y_values[-1] + y_step
self.x_values.append(x)
self.y_values.append(y)
15.4.2 绘制随机漫步图
import matplotlib.pyplot as plt
# 创建一个RandomWalk实例,并调用fill_walk()
rw = RandomWalk()
rw.fill_walk()
# 将所有的点都绘制出来
plt.style.use('classic')
fig, ax = plt.subplots()
ax.scatter(rw.x_values, rw.y_values, s=15)
plt.show()
15.4.3 模拟多次随机漫步
每次运行都会生成不同的随机漫步,因为随机性的存在。如果你想继续漫步,程序会循环运行直到你选择退出,只需将上述代码放入一个 while 循环即可。
15.4.4 给点着色
使用颜色映射来显示漫步中点的先后顺序。将点的顺序列表传递给参数 c,并指定 cmap:
point_numbers = range(rw.num_points)
ax.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues, edgecolor='none', s=15)
15.4.5 重新绘制起点和终点
将起点和终点突出显示,能更清楚地看出漫步的轨迹:
ax.scatter(0, 0, c='green', edgecolors='none', s=100) # 起点
ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none', s=100) # 终点
c- point_numbers 颜色值数组 (点的序号 0, 1, 2, 3...)
cmap- plt.cm.Blues 颜色映射 :蓝色渐变
轨迹可视化 - 能看出随机游走的先后顺序
15.4.6 起点和终点
ax.scatter(0, 0, c='green', edgecolors='none', s=100)
ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none', s=100)

15.4.7 隐藏坐标轴
隐藏坐标轴让随机漫步图看起来更整洁:
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
15.4.8 调整图表尺寸以适应屏幕
figure() 函数可指定图表的宽度、高度、分辨率和背景色。在创建图表前设置:
fig, ax = plt.subplots(figsize=(10, 6), dpi=128)
15.5 使用 Plotly 绘制掷骰子模拟
Plotly 可以创建交互式图表,特别适合在浏览器中展示。使用 Plotly 模拟掷骰子的结果。
15.5.1 安装 Plotly
python -m pip install --user plotly
python -m pip install --user pandas
注意:本教程中的示例使用 Plotly 4.0,安装后请导入
plotly.graph_objs。
15.5.2 创建 Die 类
from random import randint
class Die:
"""表示一个骰子的类"""
def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides
def roll(self):
"""返回一个介于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)
15.5.3 掷骰子并对结果进行分析
创建一个6面骰子和一个10面骰子,同时掷它们50000次,计算点数之和:
# 从 DieClass 模块导入 Die 类(骰子类)
from DieClass import Die
# 创建两个骰子实例
die_1 = Die() # 创建默认 6 面骰子
die_2 = Die(10) # 创建 10 面骰子
# 创建空列表,用于存储每次投掷的结果
results = []
# 模拟投掷骰子 49,999 次(5_0000 是 Python 的数字分隔写法,等于 50000)
for roll_num in range(1, 5_0000):
# 投掷两个骰子,将结果相加
result = die_1.roll() + die_2.roll()
# 将结果添加到列表中
results.append(result)
# print(results) # 调试用,查看所有结果(数据量太大,已注释) [11, ...(50000个)..., 5, 12]
# ========== 分析结果 ==========
# 创建空列表,用于存储每个结果出现的频率
frequencies = []
# 计算最大可能的结果值(6 + 10 = 16)
max_result = die_1.num_sides + die_2.num_sides
# 遍历所有可能的结果(从 2 到 16)
for value in range(2, max_result + 1):
# 统计该结果在 results 列表中出现的次数
frequency = results.count(value)
# 将频率添加到 frequencies 列表中
frequencies.append(frequency)
print(frequencies)
# 分析频率 2到16出现频率
# [781, 1682, 2516, 3262, 4050, 4940, 5159, 5059, 4936, 5053, 4228, 3315, 2526, 1628, 864]
# [823, 1770, 2432, 3350, 4216, 4986, 4865, 4971, 4876, 5140, 4134, 3418, 2494, 1695, 829]
15.5.4 绘制直方图
简单版 Plotly Express (高级 API)
from DieClass import Die
import plotly.express as px
# 前面的代码
...
# 对结果进行可视化
fig = px.bar(x=range(2, max_result + 1), y=frequencies)
fig.show()

可自定义 Plotly Graph Objects (底层 API)
使用 Plotly 的 bar 方法绘制直方图,并显示交互式图表:
from plotly.graph_objs import Bar, Layout
from plotly import offline
# 可视化结果
x_values = list(range(2, max_result + 1))
data = [Bar(x=x_values, y=frequencies)]
x_axis_config = {'title': 'Result', 'dtick': 1}
y_axis_config = {'title': 'Frequency of Result'}
my_layout = Layout(title='Results of rolling a D6 and a D10 50000 times',
xaxis=x_axis_config, yaxis=y_axis_config)
offline.plot({'data': data, 'layout': my_layout}, filename='d6_d10.html')
注意:
dtick: 1告诉Plotly显示每个坐标轴刻度标签;offline.plot()生成一个HTML文件并在浏览器中自动打开。
15.5.5 同时掷两个骰子
上述示例已演示了同时掷两个骰子的场景。你可以创建任意数量、任意面数的骰子组合,只需修改 Die 的实例化参数(例如 Die(8) 表示8面骰子)。
✍️ 动手试一试(课后练习)
根据教程内容,尝试完成以下练习来巩固数据可视化的知识:
- 练习 15.1 立方:数字的立方指其三次方。请绘制一个图表,显示前5个整数的立方值,再绘制一个图表显示前5000个整数的立方值。
- 练习 15.2 彩色立方:在前一个练习绘制的立方图上应用颜色映射。
- 练习 15.3 分子运动:修改随机漫步程序,让分子每次移动的步长是随机选择的1到100之间的整数,并让方向也是随机的。绘制这种分子运动轨迹图。
- 练习 15.6 同时掷两个骰子:创建一个同时掷两个6面骰子100000次的程序,使用Plotly绘制结果直方图,并统计每种点数之和出现的频率。

浙公网安备 33010602011771号