一、模拟掷一个骰子
1、什么是Plotly
Plotly 是一个强大的数据可视化工具,主要能干以下几件事:
- 创建多种图表:支持丰富的图表类型,包括折线图、柱状图、散点图等基础图表,也能绘制等高线图、热力图、箱线图等复杂图表,还可制作地图、散点地图等地理可视化图表以及 3D 图表,满足不同数据展示需求。
- 实现交互操作:生成的图表具有高度交互性,用户可通过鼠标悬停查看数值和标签,能进行缩放、平移操作来查看细节,还可点击图例动态显示或隐藏数据系列,三维图表还能进行旋转,方便深入探索数据。
- 高度自定义样式:允许用户对图表的标题、坐标轴标签、刻度、网格线等基本元素,以及数据点的标记样式、线条样式、填充颜色等进行自定义,对于地图和 3D 图表,还能设置投影方式、视角、光照效果等,打造个性化图表。
- 集成与分享:可与 Jupyter Notebook 集成,便于在数据分析过程中直接可视化。借助 Dash 框架能创建 Web 应用,用于构建数据可视化仪表盘。生成的图表可导出为 HTML 文件,也能保存为高清 PNG、SVG 等图片格式,方便分享和嵌入到其他文档或网页中。
- 实时数据可视化:通过更新数据源,能够实现实时更新图表,适用于实时监控等场景,如实时股票价格监控、服务器性能监控等。
2、安装Plotly
file->settings->Project:xxx->Python Interpreter->点击+->输入Plotly安装即可。

3、编写骰子类
python
from random import randint
class Die:
"""表示一个骰子的类"""
def __init__(self, sides = 6):
"""初始化骰子的属性
sides: 骰子的面数,默认为6面
"""
self.sides = sides # 存储骰子的面数
def roll(self):
"""模拟掷骰子,返回一个1到sides之间的随机整数"""
return randint(1, self.sides) # 使用randint生成随机数
4、编写掷骰子的类
python
from plotly.graph_objs import Layout, Bar
from plotly import offline
from Die import Die # 导入自定义的骰子类
# 创建一个六面骰子实例
die = Die()
# 掷骰子100次并存储结果
results = []
for roll_num in range(100):
results.append(die.roll()) # 调用Die类的roll方法获取随机结果
print(results) # 打印所有掷骰子的结果
# 分析结果:统计每个点数出现的频率
frequencies = []
for value in range(1, die.sides + 1): # 遍历1到骰子面数的所有可能值
frequency = results.count(value) # 统计每个值在结果中出现的次数
frequencies.append(frequency) # 将频率添加到列表
print(frequencies) # 打印频率统计结果
# 数据可视化:使用Plotly创建柱状图
x_values = list(range(1, die.sides + 1)) # x轴为骰子的各个面
data = [Bar(x=x_values, y=frequencies)] # 创建柱状图数据对象
# 配置坐标轴
x_axis_config = {'title': '骰子点数'} # x轴标题
y_axis_config = {'title': '出现频率'} # y轴标题
# 设置图表布局
my_layout = Layout(
title='投掷一个D6骰子100次的结果分布', # 图表标题
xaxis=x_axis_config, # 应用x轴配置
yaxis=y_axis_config # 应用y轴配置
)
# 生成HTML文件并打开浏览器显示图表
# 注意:此处路径中的转义字符需要使用双反斜杠或原始字符串
offline.plot(
{'data': data, 'layout': my_layout},
filename=r'D:\py_projects\test1\die_visual.html' # 保存为HTML文件
)

代码解释:
1. 导入必要的库和模块
python
from plotly.graph_objs import Layout, Bar
from plotly import offline
from Die import Die # 导入自定义的骰子类
Layout
和Bar
是 Plotly 中用于创建图表布局和柱状图的类。offline
模块允许在本地生成 HTML 文件来显示图表,无需连接网络。Die
是一个自定义类,用于模拟骰子。
2. 创建骰子实例并掷骰子
python
# 创建一个六面骰子实例
die = Die()
# 掷骰子100次并存储结果
results = []
for roll_num in range(100):
results.append(die.roll()) # 调用Die类的roll方法获取随机结果
print(results) # 打印所有掷骰子的结果
die = Die()
创建一个默认的六面骰子。- 通过循环 100 次调用
die.roll()
方法模拟掷骰子,并将每次结果存储在results
列表中。 - 最后打印出所有 100 次掷骰子的结果。
3. 分析结果:统计每个点数出现的频率
python
# 分析结果:统计每个点数出现的频率
frequencies = []
for value in range(1, die.sides + 1): # 遍历1到骰子面数的所有可能值
frequency = results.count(value) # 统计每个值在结果中出现的次数
frequencies.append(frequency) # 将频率添加到列表
print(frequencies) # 打印频率统计结果
frequencies
列表用于存储每个点数出现的次数。range(1, die.sides + 1)
生成从 1 到 6 的整数(假设是六面骰子)。results.count(value)
统计每个点数在results
列表中出现的次数,并将结果添加到frequencies
列表。- 最后打印出每个点数的出现频率。
4. 数据可视化:创建柱状图
python
# 数据可视化:使用Plotly创建柱状图
x_values = list(range(1, die.sides + 1)) # x轴为骰子的各个面
data = [Bar(x=x_values, y=frequencies)] # 创建柱状图数据对象
x_values
是一个包含 1 到 6 的列表,表示骰子的六个面。Bar
对象创建一个柱状图,其中x
轴为骰子的各个面,y
轴为对应的出现频率。data
列表包含这个Bar
对象,用于后续的图表创建。
5. 配置图表布局
python
# 配置坐标轴
x_axis_config = {'title': '骰子点数'} # x轴标题
y_axis_config = {'title': '出现频率'} # y轴标题
# 设置图表布局
my_layout = Layout(
title='投掷一个D6骰子100次的结果分布', # 图表标题
xaxis=x_axis_config, # 应用x轴配置
yaxis=y_axis_config # 应用y轴配置
)
x_axis_config
和y_axis_config
分别设置 x 轴和 y 轴的标题。Layout
对象定义了整个图表的布局,包括标题和坐标轴配置。
6. 生成 HTML 文件并显示图表
python
# 生成HTML文件并打开浏览器显示图表
# 注意:此处路径中的转义字符需要使用双反斜杠或原始字符串
offline.plot(
{'data': data, 'layout': my_layout},
filename='D:\\py_projects\\test1\\die_visual.html' # 保存为HTML文件
)
offline.plot()
方法将数据和布局组合成一个完整的图表,并生成一个 HTML 文件。filename
参数指定了 HTML 文件的保存路径,使用原始字符串(前面加r
)避免反斜杠转义问题。- 运行代码后,会自动在浏览器中打开生成的 HTML 文件,显示柱状图。
二、模拟掷两个骰子
python
from plotly.graph_objs import Layout, Bar
from plotly import offline
from Die import Die
# 创建两个六面骰子实例(D6)
die1 = Die()
die2 = Die()
# 掷骰子多次并将每次结果存储到列表中
results = []
for roll_num in range(1000): # 增加投掷次数以获得更平滑的分布
result = die1.roll() + die2.roll() # 计算两个骰子的点数之和
results.append(result)
# 分析结果:统计每个可能的点数之和出现的频率
frequencies = []
max_value = die1.sides + die2.sides # 最大可能值为两个骰子面数之和(6+6=12)
# 注意:两个骰子的最小和为2(1+1),因此从2开始循环
for value in range(2, max_value + 1):
frequency = results.count(value) # 统计每个和值出现的次数
frequencies.append(frequency)
# 数据可视化:使用Plotly创建柱状图
x_values = list(range(2, max_value + 1)) # x轴为所有可能的和值(2到12)
data = [Bar(x=x_values, y=frequencies)] # 创建柱状图数据
# 配置图表布局和坐标轴
x_axis_config = {
'title': '两个骰子的点数之和', # x轴标题
'dtick': 1 # 设置x轴刻度间隔为1,确保每个和值都显示
}
y_axis_config = {
'title': '出现频率' # y轴标题
}
my_layout = Layout(
title='掷两个六面骰子1000次的结果分布', # 图表标题
xaxis=x_axis_config, # 应用x轴配置
yaxis=y_axis_config # 应用y轴配置
)
# 生成HTML文件并在浏览器中显示图表
offline.plot(
{'data': data, 'layout': my_layout},
filename=r'D:\py_projects\test1\two_dice_visualization.html' # 保存路径
)

三、读取csv文件数据绘制数据图
1、打印头文件及其位置
python
import csv
# 指定CSV文件路径
fileName = 'D:\\py_projects\\data\\sitka_weather_07-2018_simple.csv'
# 打开CSV文件
with open(fileName) as csvfile:
# 创建CSV阅读器对象
reader = csv.reader(csvfile)
head_row = next(reader)
for index,row in enumerate(head_row):
print(index,row)

代码解释:
1. 导入 CSV 模块
python
import csv
- 作用:导入 Python 内置的
csv
模块,用于处理 CSV(逗号分隔值)格式文件 - CSV 模块提供了读取和写入 CSV 文件的功能
2. 指定 CSV 文件路径
python
fileName = 'D:\\py_projects\\data\\sitka_weather_07-2018_simple.csv'
- 作用:定义要读取的 CSV 文件的路径
- 路径使用双反斜杠
\\
是为了转义特殊字符,确保路径正确解析 - 示例文件是一个天气数据文件(可能包含日期、温度等信息)
3. 打开并读取 CSV 文件
python
with open(fileName) as csvfile:
reader = csv.reader(csvfile)
with open(fileName) as csvfile
:使用with
语句打开文件,自动管理文件资源(无需手动关闭)csv.reader(csvfile)
:创建一个 CSV 阅读器对象,用于逐行读取文件内容- 默认情况下,
csv.reader
会将每行数据按逗号分隔并转换为列表
4. 获取表头行
python
head_row = next(reader)
next(reader)
:获取迭代器的下一行数据(即第一行)- 通常 CSV 文件的第一行是表头,包含列名信息
- 执行这一步后,阅读器的指针会移到第二行,后续读取将从第二行开始
5. 打印表头信息
python
for index, row in enumerate(head_row):
print(index, row)
enumerate(head_row)
:将表头列表转换为带索引的枚举对象index
:列的索引(从 0 开始)row
:列名(表头内容)
2、读取csv数据
python
import csv
# 指定CSV文件路径
fileName = 'D:\\py_projects\\data\\sitka_weather_07-2018_simple.csv'
# 打开CSV文件
with open(fileName) as csvfile:
# 创建CSV阅读器对象
reader = csv.reader(csvfile)
# 读取并存储文件头行(列名)
header_row = next(reader)
# 初始化最高温度列表
highs = []
# 遍历文件中剩余的每一行数据
for row in reader:
# 提取并转换最高温度数据(假设在第6列,索引为5)
high = int(row[5])
# 将转换后的温度添加到列表中
highs.append(high)
# 打印提取的最高温度列表
print(highs)

代码解释:
1. 准备一个空列表,用来装最高温度
python
highs = []
highs = []
:就像准备一个空篮子,后面要把每天的最高温度 "放进去"。其存储的数据类型为列表
2. 一行一行地读表格,提取最高温度
python
for row in reader:
print(row)
high = int(row[5])
highs.append(high)
for row in reader
:让阅读器逐行读取表格的剩余内容(从第二行开始)。print(row)
:每读一行,就把这行内容打印出来看看(比如['2018-07-01', '16.7', '10.0']
)。这里输出的是元组row[5]
:从当前行中取出第 6 个数据(比如'16.7'
)。- 为什么是 5? 因为列表索引从 0 开始,所以第 6 个元素的索引是 5。
int(row[5])
:把温度从文本(比如'16.7'
)变成数字(比如16
)。highs.append(high)
:把转换后的温度数字放进篮子(highs
列表)里。
3、绘制温服图表
python
import csv
import matplotlib.pyplot as plt
# 指定CSV文件路径
fileName = 'D:\\py_projects\\data\\sitka_weather_07-2018_simple.csv'
# 打开CSV文件
with open(fileName) as csvfile:
# 创建CSV阅读器对象
reader = csv.reader(csvfile)
head_row = next(reader)
highs = []
for row in reader:
highs.append(int(row[5]))
#绘制表格
plt.style.use('ggplot') #设置图表风格为 "ggplot"
fig, ax = plt.subplots()
ax.plot(highs)
#设置表格样式
ax.set_title('The highest temperature for each month in 2018',fontsize=11)
ax.set_xlabel('',fontsize=11)
ax.set_ylabel('temperature F',fontsize=11)
ax.tick_params(axis='both', which='major', labelsize=10)
plt.show() #显示绘制好的图表窗口。

代码解释:
1、创建图表与坐标轴
python
fig, ax = plt.subplots()
plt.subplots()
:创建一个图表 (figure) 和一个子图 (axes) 对象。fig
:表示整个图表窗口。ax
:表示实际的绘图区域(坐标系)。
2、绘制折线图
python
ax.plot(highs)
ax.plot(highs)
:在坐标系上绘制折线图。- X 轴:默认是数据点的索引(0-11,对应 1-12 月)。
- Y 轴:
highs
列表中的值(最高气温)。
3、设置图表标题和坐标轴标签
python
ax.set_title('The highest temperature for each month in 2018', fontsize=11)
ax.set_xlabel('', fontsize=11)
ax.set_ylabel('temperature F', fontsize=11)
-
标题设置:
ax.set_title()
:设置图表标题为 "The highest temperature for each month in 2018"(2018 年每月最高气温)。fontsize=11
:标题文字大小为 11pt。
-
X 轴标签:
ax.set_xlabel('')
:X 轴标签为空字符串(可能后续会补充月份信息)。
-
Y 轴标签:
ax.set_ylabel('temperature F')
:Y 轴标签为 "temperature F"(华氏温度)。
4、设置刻度标签大小
python
ax.tick_params(axis='both', which='major', labelsize=10)
ax.tick_params()
:设置坐标轴刻度的样式。axis='both'
:同时设置 X 轴和 Y 轴。which='major'
:只设置主刻度(默认每个月一个刻度)。labelsize=10
:刻度标签文字大小为 10pt。
4、在图表中添加时间
python
import csv
import matplotlib.pyplot as plt
from datetime import datetime
# 指定CSV文件路径(包含2018年7月天气数据)
fileName = 'D:\\py_projects\\data\\sitka_weather_07-2018_simple.csv'
with open(fileName) as csvfile:
reader = csv.reader(csvfile)
head_row = next(reader) # 获取表头行
# 创建空列表存储最高温度和日期
highs, dates = [], []
# 遍历CSV文件的每一行数据
for row in reader:
# 获取最高温度列(索引5),转换为整数并添加到列表
highs.append(int(row[5]))
# 日期处理:
# 1. 从第3列(row[2])获取原始日期字符串(格式:YYYY-MM-DD)
# 2. 使用datetime.strptime()将字符串解析为datetime对象
# - '%Y-%m-%d' 是日期格式指令,对应年-月-日
current_date = datetime.strptime(row[2], '%Y-%m-%d')
dates.append(current_date) # 将datetime对象存入列表
# 绘制温度随日期变化的折线图
plt.style.use('ggplot') # 设置图表风格为 "ggplot"(类似R语言的风格)
fig, ax = plt.subplots() # 创建图表和坐标轴对象
# 绘制折线图:
# - X轴:日期列表(datetime对象)
# - Y轴:最高温度列表
# - c='red':设置线条颜色为红色
ax.plot(dates, highs, c='red')
# 设置图表标题和样式
ax.set_title('The highest temperature for each month in 2018', fontsize=11)
# 自动格式化X轴日期标签:
# - 旋转日期标签避免重叠
# - 智能选择日期显示格式(如只显示月份、日等)
fig.autofmt_xdate()
ax.set_xlabel('', fontsize=11) # X轴标签(为空,可根据需要添加)
ax.set_ylabel('temperature F', fontsize=11) # Y轴标签(温度单位:华氏度)
ax.tick_params(axis='both', which='major', labelsize=10) # 设置刻度标签大小
plt.show() # 显示绘制好的图表窗口

5、绘制一整年的气温变化图表
只需要将文件变为
python
fileName = 'D:\\py_projects\\data\\sitka_weather_2018_simple.csv'

6、添加最低温度
python
import csv
import matplotlib.pyplot as plt
from datetime import datetime
fileName = 'D:\\py_projects\\data\\sitka_weather_2018_simple.csv'
with open(fileName) as csvfile:
reader = csv.reader(csvfile)
head_row = next(reader)
lows,highs,dates = [],[] ,[] #获取最高温度,最低温度和时间
for row in reader:
lows.append(float(row[6]))
highs.append(int(row[5]))
current_date = datetime.strptime(row[2], '%Y-%m-%d')
dates.append(current_date)
#绘制表格
plt.style.use('ggplot')
fig, ax = plt.subplots()
ax.plot(dates,highs,c = 'red') #绘制最高温度曲线
ax.plot(dates,lows,c = 'blue') #绘制最低温度曲线
#设置表格样式
ax.set_title('The highest temperature for each month in 2018',fontsize=11)
fig.autofmt_xdate()
ax.set_xlabel('',fontsize=11)
ax.set_ylabel('temperature F',fontsize=11)
ax.tick_params(axis='both', which='major', labelsize=10)
plt.show()

7、给图表区域着色
python
import csv
import matplotlib.pyplot as plt
from datetime import datetime
fileName = 'D:\\py_projects\\data\\sitka_weather_2018_simple.csv'
with open(fileName) as csvfile:
reader = csv.reader(csvfile)
head_row = next(reader)
lows,highs,dates = [],[] ,[] #获取最高温度,最低温度和时间
for row in reader:
lows.append(float(row[6]))
highs.append(int(row[5]))
current_date = datetime.strptime(row[2], '%Y-%m-%d')
dates.append(current_date)
#绘制表格
plt.style.use('ggplot')
fig, ax = plt.subplots()
# 绘制最高温度曲线
# - dates: X轴数据(日期列表)
# - highs: Y轴数据(最高温度列表)
# - c='red': 曲线颜色为红色
# - alpha=0.5: 曲线透明度为50%(使曲线半透明,便于查看重叠区域)
ax.plot(dates, highs, c='red', alpha=0.5)
# 绘制最低温度曲线
# - dates: X轴数据(与最高温度使用相同的日期)
# - lows: Y轴数据(最低温度列表)
# - c='blue': 曲线颜色为蓝色
# - alpha=0.5: 曲线透明度为50%
ax.plot(dates, lows, c='blue', alpha=0.5)
# 填充最高温度和最低温度之间的区域
# - dates: X轴数据(日期)
# - highs: 上边界(最高温度)
# - lows: 下边界(最低温度)
# - facecolor='blue': 填充颜色为蓝色
# - alpha=0.1: 填充区域透明度为10%(几乎透明,仅作视觉区分)
ax.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
#设置表格样式
ax.set_title('The highest temperature for each month in 2018',fontsize=11)
fig.autofmt_xdate()
ax.set_xlabel('',fontsize=11)
ax.set_ylabel('temperature F',fontsize=11)
ax.tick_params(axis='both', which='major', labelsize=10)
plt.show()
