在前两篇文章中,笔者主要介绍了matplotlib
绘制折线图和散点图的基本使用。
相信大家已经发现了用Python
实现可视化的便捷性。
在本篇中,笔者将使用Python
可视化软件包Pygal
生成可伸缩的矢量图形文件。
本篇,我们将分析掷骰子的结果。
如果掷出一个骰子,有相等的机会掷出从1到6的任何数字。
但是,当使用两个骰子时,两个骰子的点数和更可能是某些特定数字而不是其他数字。
我们将尝试通过收集模拟掷骰子的数据来确定最可能出现的数字。
然后,我们将绘制大量掷骰结果,以确定哪些结果比其他结果更有可能。
安装Pygal
pip install Pygal
对于python开发者而言,安装第三方库已不是什么难事。笔者不在此处赘述。
要查看使用Pygal
可以进行什么样的可视化,可访问图表类型的库:http://www.pygal.org//,单击Documentation
,然后单击Chart types
,每个示例都包含源代码。
创建骰子类
创建一个模拟单个骰子滚动的类:
from random import randint
class Die():
"""模拟单个骰子"""
def roll(self):
""""随机返回一个从1到6的值"""
return randint(1, 6)
创建一个Die类,用于创建骰子实例。
当然,这个类很简单,也可以直接使用random类模拟单个骰子的结果。
模拟掷单个骰子
from die import Die
# 实例化一个骰子
die = Die()
# 模拟100次掷骰子,并将结果存放在列表中
results = []
for roll_num in range(100):
result = die.roll()
results.append(result)
print(results)
在第4行创建一个Die
的实例。
第8行,通过循环模拟100次掷骰子,并将每次的模拟结果添加到result
列表中。
将result
打印出来(每次结果都不同)。
[3, 3, 2, 4, 4, 5, 6, 1, 5, 3, 2, 4, 4, 3, 3, 6, 4, 5, 3, 2,
6, 3, 5, 5, 6, 2, 4, 2, 3, 5, 3, 4, 6, 2, 3, 2, 2, 6, 2, 5,
2, 4, 1, 4, 4, 4, 6, 5, 3, 4, 1, 5, 3, 3, 5, 3, 2, 4, 1, 4,
4, 5, 6, 4, 6, 6, 5, 1, 5, 3, 2, 1, 5, 2, 5, 5, 4, 3, 1, 5,
5, 5, 6, 3, 3, 3, 1, 5, 2, 4, 2, 6, 1, 4, 3, 1, 5, 1, 6, 6]
分析结果
我们通过统计每个数字出现次数来分析掷一个骰子的结果:
from die import Die
die = Die()
results = []
for roll_num in range(1000):
result = die.roll()
results.append(result)
# 分析结果
frequencies = []
for value in range(1, 7):
frequency = results.count(value)
frequencies.append(frequency)
print(frequencies)
第6行,因为我们使用Pygal
来分析而不是打印结果,因此我们将循环次数增加到1000。
在第11行,创建一个frequencies
空列表用于存放各结果出现次数。
在第12行的for循环中,分别统计各结果出现次数并添加到frequencies
。
打印frequencies
:
[181, 172, 181, 151, 152, 163]
这个结果看起来是合理的:没有一个频率比其他任何频率高得很多或低的很多。
接下来让我们可视化这些结果。
绘制直方图
通过列表frequencies
,我们可以制作结果的直方图。
直方图是显示某些结果出现频率的条形图。
import pygal
from die import Die
die = Die()
results = []
for roll_num in range(1000):
result = die.roll()
results.append(result)
frequencies = []
for value in range(1, 7):
frequency = results.count(value)
frequencies.append(frequency)
# 结果可视化
hist = pygal.Bar()
hist.title = "掷1000次单个骰子的结果"
hist.x_labels = ['1', '2', '3', '4', '5', '6']
hist.x_title = "结果"
hist.y_title = "结果频次"
hist.add('骰子', frequencies)
hist.render_to_file('die_visual.svg')
第17行,我们通过创建pygal.Bar()
的实例hist
来制作条形图。
然后,我们设置hist
的title
属性,使用掷骰子的可能结果作为x
轴的标签,并为每个轴添加标题。
第24行,我们使用add()
在向图表添加一系列值(向其传递要添加的一组值的标签以及要在图表上显示的值列表)。
最后,我们将图表呈现为SVG文件,该文件需要带有的文件名和扩展名.svg
。
查看svg
图的最简单方法是在Web浏览器中。
您会看到类似于下图中的图表。
![](https://i-blog.csdnimg.cn/blog_migrate/0cc3cfcdb350a41a68a03a1cfbd1ac90.gif)
可以注意到,Pygal
使图表具有交互性:将光标悬停在图表中的任何条形上,您将看到与之相关的数据。在同一图表上绘制多个数据集时,此功能特别有用。
掷两个骰子
掷两个骰子会产生更大的数目,并且结果分配会有所不同。
让我们修改代码以创建两个骰子,来模拟掷出一对骰子的结果。
每次掷这两个骰子,我们将这两个骰子的结果相加,并将结果存储在result
中。
新建die_visual.py的副本dice_visual.py,并进行以下更改:
import pygal
from die import Die
# 创建两个骰子实例
die1 = Die()
die2 = Die()
results = []
for roll_num in range(1000):
result = die1.roll() + die2.roll()
results.append(result)
frequencies = []
max_result = 6 + 6
for value in range(2, max_result + 1):
frequency = results.count(value)
frequencies.append(frequency)
hist = pygal.Bar()
hist.title = "两个骰子掷1000次的结果"
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
hist.x_title = "结果"
hist.y_title = "结果频次"
hist.add('骰子1 + 骰子2', frequencies)
hist.render_to_file('dice_visual.svg')
创建两个Die
实例后,我们掷骰子,并计算两个骰子结果的总和。
可能的最大结果12
是两个骰子上最大数目的总和,我们将其存储在max_result
中。
最小的结果2
是两个骰子上最小数目的总和。
当我们分析结果时,我们会计算介于2和最大结果之间的每个值的结果的次数(当然,我们可以直接使用range(2, 13)
)。
创建图表时,我们将修改x轴和数据的标题和标签(如果x_labels
列表很长,可以根据规律编写一个列表生成式)。
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/0449f933fd2cfa00659c234fdb208f46.gif)
Pygal
对掷骰子结果建模的能力为我们提供了探索这种现象的极大的自由度。
在短短几分钟内,我们可以模拟大量掷骰子实验。
总结
通过这三篇内容的了解,相信您基本掌握了
- 如何使用
matplotlib
创建简单图, - 了解了如何使用散点图探索随机游走
- 如何使用
Pygal
创建直方图 - 如何使用直方图来探索不同大小的掷骰子的结果
用代码生成自己的数据集是一种有趣且强大的建模和探索各种现实情况的方法。
当然,最重要的是学会如何高效的使用工具,希望我的文章对您有帮助。