数据可视化(三)

使用 Pygal模拟掷骰子

安装 Pygal

使用pip 来安装Pygal,代码如下:

pip install pygal

创建 Die 类

下面的类模拟掷一个骰子:
die.py

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)

方法__init__() 接受一个可选参数。创建这个类的实例时,如果没有指定任何实参,面数默认为6;如果指定了实参,这个值将用于设置骰子的面数。骰子是根据面数命名的,6面的骰子名为D6,8面的骰子名为D8,以此类推。
方法roll() 使用函数randint() 来返回一个1和面数之间的随机数。这个函数可能返回起始值1、终止值num_sides 或这两个值之间的任何整数。

掷骰子

使用这个类来创建图表前,先来掷D6骰子,将结果打印出来,并检查结果是否合理:
die_visual.py

from die import Die
# 创建一个D6
die = Die()
# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)
print(results)

我们创建了一个Die 实例,其面数为默认值6,同时我们掷骰子100次,并将每次的结果都存储在列表results 中。下面是一个示例结果集:

[1, 2, 2, 1, 4, 2, 5, 2, 6, 3, 5, 5, 3, 4, 1, 6, 3, 1, 2, 6, 1, 4, 1, 1, 2, 1, 2, 2, 6, 3, 2, 3, 2, 5, 5, 1, 6, 2, 5, 4, 3, 5, 5, 6, 5, 4, 1, 6, 4, 5, 5, 6, 1, 4, 6, 5, 5, 6, 4, 3, 3, 1, 5, 5, 1, 5, 4, 4, 6, 3, 2, 1, 4, 3, 2, 2, 1, 2, 4, 3, 2, 3, 6, 2, 2, 4, 2, 2, 4, 5, 1, 4, 6, 5, 2, 6, 5, 5, 5, 4]

进程已结束,退出代码为 0

通过快速扫描这些结果可知,Die 类看起来没有问题。我们见到了值1和6,这表明返回了最大和最小的可能值;我们没有见到0或7,这表明结果都在正确的范围内。我们还看到 了1~6的所有数字,这表明所有可能的结果都出现了。

分析结果

为分析掷一个D6骰子的结果,我们计算每个点数出现的次数:
die_visual.py

from die import Die
# 创建一个D6
die = Die()
# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000):
    result = die.roll()
    results.append(result)
# 分析结果
frequencies = []
for value in range(1, die.num_sides+1):
    frequency = results.count(value)
    frequencies.append(frequency)

print(frequencies)
print(results)

由于我们将使用Pygal来进行分析,而不是将结果打印出来,因此可以将模拟掷骰子的次数增加到1000。为分析结果,我们创建了空列表frequencies ,用于存储每种点数出现的次数。我们遍历可能的点数(这里为1~6),计算每种点数在results 中出现了多少次,并将这个值附加到列表frequencies 的末尾。 接下来,我们在可视化之前将这个列表打印出来.

绘制直方图

有了频率列表后,我们就可以绘制一个表示结果的直方图。直方图是一种条形图,指出了各种结果出现的频率。创建这种直方图的代码如下:

from die import Die
import pygal
# 创建一个D6
die = Die()
# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000):
    result = die.roll()
    results.append(result)
# 分析结果
frequencies = []
for value in range(1, die.num_sides+1):
    frequency = results.count(value)
    frequencies.append(frequency)
# 对结果进行可视化
hist = pygal.Bar()
hist.title = "Results of rolling one D6 1000 times."
hist.x_labels = ['1', '2', '3', '4', '5', '6']
hist.x_title = "Result"
hist.y_title = "Frequency of Result"
hist.add('D6', frequencies)
hist.render_to_file('die_visual.svg')
print(frequencies)

为创建条形图,我们创建了一个pygal.Bar() 实例,并将其存储在hist 中。接下来,我们设置hist 的属性title (用于标示直方图的字符串),将掷D6骰子的可 能结果用作 x 轴的标签,并给每个轴都添加了标题。我们使用add() 将一系列值添加到图表中(向它传递要给添加的值指定的标签,还有一个列表,其中包含 将出现在图表中的值)。最后,我们将这个图表渲染为一个SVG文件,这种文件的扩展名必须为.svg。
要查看生成的直方图,最简单的方式是使用Web浏览器。为此,在任何Web浏览器中新建一个标签页,再在其中打开文件die_visual.svg(它位于die_visual.py所在的文件夹中)。你将看到一个类似于下图所示的图表
在这里插入图片描述

同时掷两个骰子

同时掷两个骰子时,得到的点数更多,结果分布情况也不同。下面来修改前面的代码,创建两个D6骰子,以模拟同时掷两个骰子的情况。每次掷两个骰子时,我们都将两个骰子 的点数相加,并将结果存储在results 中。代码如下:
dice_visual.py

import pygal
from die import Die
# 创建两个D6骰子
die_1 = Die()
die_2 = Die()
# 掷骰子多次,并将结果存储到一个列表中
results = []
for roll_num in range(1000):
    result = die_1.roll() + die_2.roll()
    results.append(result)
# 分析结果
frequencies = []
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result+1):
    frequency = results.count(value)
    frequencies.append(frequency)
# 可视化结果
hist = pygal.Bar()
hist.title = "Results of rolling two D6 dice 1000 times."
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
hist.x_title = "Result"
hist.y_title = "Frequency of Result"
hist.add('D6 + D6', frequencies)
hist.render_to_file('dice_visual.svg')

创建两个Die 实例后,我们掷骰子多次,并计算每次的总点数。可能出现的最大点数12为两个骰子的最大可能点数之和,我们将这个值存储在了max_result 中)。可能出现的最小总点数2为两个骰子的最小可能点数之和。分析结果时,我们计算2到max_result 的各种点数出现的次数。我们原本可以使用range(2, 13) ,但这只适用于两个D6骰子。模拟现实世界的情形时,最好编写可轻松地模拟各种情形的代码。前面的代码让我们能够模拟掷任何两个骰子的情形,而不管这些骰子有多少面。 创建图表时,我们修改了标题、x 轴标签和数据系列。
运行结果如下所示:
在这里插入图片描述

同时掷两个面数不同的骰子

下面来创建一个6面骰子和一个10面骰子,看看同时掷这两个骰子50 000次的结果如何:
different_dice.py

from die import Die
import pygal
# 创建一个D6和一个D10
die_1 = Die()
die_2 = Die(10)
# 掷骰子多次,并将结果存储在一个列表中
results = []
for roll_num in range(50000):
    result = die_1.roll() + die_2.roll()
    results.append(result)
# 分析结果
frequencies = []
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result + 1):
    frequency = results.count(value)
    frequencies.append(frequency)
# 可视化结果
hist = pygal.Bar()
hist.title = "Results of rolling a D6 and a D10 50,000 times."
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']
hist.x_title = "Result"
hist.y_title = "Frequency of Result"
hist.add('D6 + D10', frequencies)
hist.render_to_file('dice_visual.svg')

运行结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值