Python编程从入门到实践ver3-Day1

15.3 随机游走

#random_walk.py

#15.3随机游走.py
from random import choice

class RandomWalk:
    """一个生成随机游走数据的类"""
    def __init__(self,num_points=5000):
        self.num_points = num_points

        self.x_value = [0]
        self.y_value = [0]
    
    def fill_walk(self):
    #不断游走,直至列表达到指定长度
        while len(self.x_value) < 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_value[-1] + x_step
            y = self.y_value[-1] + y_step

            self.x_value.append(x)
            self.y_value.append(y)

#rw_visual.py 

#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib
matplotlib.use('TkAgg')

from random_walk import RandomWalk

rw= RandomWalk()
rw.fill_walk()

plt.style.use('classic')
fig, ax = plt.subplots()
ax.scatter(rw.x_value,rw.y_value,s=15)
ax.set_aspect('equal')
plt.show()

这段写了很多错误,回顾bug如下

  1. class的RandomWalk应该放置在一个单独的.py文件中供调用,我一开始全写到了同一个.py文件中,导致循环引用报错;
  2. __init__方法,init前后下划线是双下划线,“_ _”,而非单下划线“_”,一开始用的单下划线导致__init__方法定义错误,一直报错;
  3. 很多拼写错误,前面定义的x_value,然后在#rw_visual.py中调用成了x_values,无语;

15.3.4 模拟多次随机游走

#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib
matplotlib.use('TkAgg')

from random_walk import RandomWalk

#模拟多次随机游走,只要程序处于活动状态就不断的模拟随机游走
#通过while循环实现
while True:
    #生成一个RandomWalk实例
    rw= RandomWalk()
    rw.fill_walk()

    plt.style.use('classic')
    fig, ax = plt.subplots()
    ax.scatter(rw.x_value,rw.y_value,s=15)
    ax.set_aspect('equal')
    plt.show()
    keep_running = input("Make another walk?(y/n):")
    if keep_running == 'n':
        break 

15.3.5 设置随机游走图的样式

根据需要着重突出的部分,利用可视化的手段在图里进行突出和强调(所以本质上自己要对数据的意义有深刻理解,可视化只是辅助理解、让图漂亮的手段而已)

1. 给点着色
#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib

from random_walk import RandomWalk

#模拟多次随机游走,只要程序处于活动状态就不断的模拟随机游走
#通过while循环实现
while True:
    #生成一个RandomWalk实例
    rw= RandomWalk()
    rw.fill_walk()
    #绘制出所有的点
    plt.style.use('classic')
    fig, ax = plt.subplots()
    #使用range生成一个数值列表,列表自带顺序
    point_numbers = range(rw.num_points)
    #将列表传递给c,这样c也有了顺序,根据顺序就能绘制不同颜色从而实现渐变色
    #指定使用Blues颜色映射
    ax.scatter(rw.x_value,rw.y_value,c=point_numbers,cmap=plt.cm.Blues,
               edgecolors='none',s=15)
    ax.set_aspect('equal')
    plt.show()
    keep_running = input("Make another walk?(y/n):")
    if keep_running == 'n':
        break 
2.重新绘制起点和终点

在所有点绘制完毕以后再绘制一次【起点】和【终点】,让二者更加突出

#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib

from random_walk import RandomWalk

#生成一个RandomWalk实例
rw= RandomWalk()
rw.fill_walk()
#绘制出所有的点
plt.style.use('classic')
fig, ax = plt.subplots()
#使用range生成一个数值列表,列表自带顺序
point_numbers = range(rw.num_points)
 #将列表传递给c,这样c也有了顺序,根据顺序就能绘制不同颜色从而实现渐变色
ax.scatter(rw.x_value,rw.y_value,c=point_numbers,cmap=plt.cm.Blues,
    edgecolors='none',s=15)
ax.set_aspect('equal')

#突出起点和终点
ax.scatter(0,0,c='green',edgecolors='none',s=100)
ax.scatter(rw.x_value[-1],rw.y_value[-1],c='red',edgecolors='none',s=100)
plt.show()

 

3.隐藏坐标轴
#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib

from random_walk import RandomWalk

#生成一个RandomWalk实例
rw= RandomWalk()
rw.fill_walk()
#绘制出所有的点
plt.style.use('classic')
fig, ax = plt.subplots()
#使用range生成一个数值列表,列表自带顺序
point_numbers = range(rw.num_points)
 #将列表传递给c,这样c也有了顺序,根据顺序就能绘制不同颜色从而实现渐变色
ax.scatter(rw.x_value,rw.y_value,c=point_numbers,cmap=plt.cm.Blues,
    edgecolors='none',s=15)
ax.set_aspect('equal')

#突出起点和终点
ax.scatter(0,0,c='green',edgecolors='none',s=100)
ax.scatter(rw.x_value[-1],rw.y_value[-1],c='red',edgecolors='none',s=100)

#隐藏坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

plt.show()

4.增加点的个数
#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib

from random_walk import RandomWalk

#生成一个RandomWalk实例
#增大num_numpoints的值
rw= RandomWalk(50_000)
rw.fill_walk()
#绘制出所有的点
plt.style.use('classic')
fig, ax = plt.subplots()
#使用range生成一个数值列表,列表自带顺序
point_numbers = range(rw.num_points)
 #num_points变大了,相应地把size调小,不然没法看了
ax.scatter(rw.x_value,rw.y_value,c=point_numbers,cmap=plt.cm.Blues,
    edgecolors='none',s=1)
ax.set_aspect('equal')

#突出起点和终点
ax.scatter(0,0,c='green',edgecolors='none',s=100)
ax.scatter(rw.x_value[-1],rw.y_value[-1],c='red',edgecolors='none',s=100)

#隐藏坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

plt.show()

5.调整尺寸以适应屏幕大小
#rw_visual.py
import matplotlib.pyplot as plt 
import matplotlib

from random_walk import RandomWalk

#生成一个RandomWalk实例
#增大num_numpoints的值
rw= RandomWalk(50_000)
rw.fill_walk()
#绘制出所有的点
plt.style.use('classic')

#调整生成屏幕尺寸
fig, ax = plt.subplots(figsize=(10,6), dpi=128)

#使用range生成一个数值列表,列表自带顺序
point_numbers = range(rw.num_points)
 #num_points变大了,相应地把size调小,不然没法看了
ax.scatter(rw.x_value,rw.y_value,c=point_numbers,cmap=plt.cm.Blues,
    edgecolors='none',s=1)
ax.set_aspect('equal')

#突出起点和终点
ax.scatter(0,0,c='green',edgecolors='none',s=100)
ax.scatter(rw.x_value[-1],rw.y_value[-1],c='red',edgecolors='none',s=100)

#隐藏坐标轴
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

plt.show()

15.4 使用Plotly模拟掷骰子

15.4.2创建Die类

#die.py

from random import randint

class Die:
#默认是一个六面的骰子
    def __init__(self,num_sides=6):
        self.num_sides = num_sides
#但可以赋值num_sides,即可以八面可以十二面等等
    def roll(self):
        return randint(1,self.num_sides)

15.4.3投掷骰子

#die_visual.py
from die import Die

die = Die()

results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)

print (results)

15.4.4分析结果

#die_visual.py
from die import Die

die = Die()

results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)

frequencies = []
poss_results = range(1,die.num_sides+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

print(frequencies)

这里报错了一次,

  File "die_visual分析数据.py", line 14, in <module>
    frequency=result.count(value)
              ^^^^^^^^^^^^
AttributeError: 'int' object has no attribute 'count'

检查以后发现是

     frequency=results.count(value)

被我打成了

result

count是计数,results是列表,能够被计数,result只有一次随机数据不能被计数,因此报错了。实话实说,这些bug太几把难找了,但如果理解深刻、自己定义的东西自己记好,熟练的老师傅是很容易避免的吧!

15.4.5绘制直方图

#die_visual.py
import plotly.express as px
from die import Die

die = Die()

results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)

frequencies = []
poss_results = range(1,die.num_sides+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

#对结果进行可视化
fig=px.bar(x=poss_results,y=frequencies)
fig.show()

报错,发现应该

import plotly.express as px

加载成了

import plotly as px

15.4.6定制绘图

#die_visual.py
import plotly.express as px
from die import Die

die = Die()

results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)

frequencies = []
poss_results = range(1,die.num_sides+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

#对结果进行可视化

title="Results of Rolling On D6 1000 times"
#大括号创建字典,键值对实现label的一一对应
labels={'x':'Result','y':'Frequency of Result'}
fig=px.bar(x=poss_results,y=frequencies,title=title,labels=labels)
fig.show()

15.4.7同时投掷两个骰子

#dice_visual.py
import plotly.express as px
from die import Die

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
poss_results = range(2,max_result+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

#对结果进行可视化

title="Results of Rolling Two D6 Dice 1000 Times"
#大括号创建字典,键值对实现label的一一对应
labels={'x':'Result','y':'Frequency of Result'}
fig=px.bar(x=poss_results,y=frequencies,title=title,labels=labels)
fig.show()

 

15.4.8 updata_layout方法进一步定制

#dice_visual.py
import plotly.express as px
from die import Die

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
poss_results = range(2,max_result+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

#对结果进行可视化

title="Results of Rolling Two D6 Dice 1000 Times"
#大括号创建字典,键值对实现label的一一对应
labels={'x':'Result','y':'Frequency of Result'}
fig=px.bar(x=poss_results,y=frequencies,title=title,labels=labels)

#update_layout method进行进一步定制
fig.update_layout(xaxis_dtick=1)


fig.show()

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

#dice_visual.py
import plotly.express as px
from die import Die

die_1 = Die()
die_2 = Die(10)

results = []
for roll_num in range(50_000):
    result = die_1.roll()+die_2.roll()
    results.append(result)

frequencies = []
max_result=die_1.num_sides + die_2.num_sides
poss_results = range(2,max_result+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

#对结果进行可视化

title="Results of Rolling a D6 and a D10 50,000 Times"
#大括号创建字典,键值对实现label的一一对应
labels={'x':'Result','y':'Frequency of Result'}
fig=px.bar(x=poss_results,y=frequencies,title=title,labels=labels)

#update_layout method进行进一步定制
fig.update_layout(xaxis_dtick=1)


fig.show()

15.4.10保存图形

#dice_visual.py
import plotly.express as px
from die import Die

die_1 = Die()
die_2 = Die(10)

results = []
for roll_num in range(50_000):
    result = die_1.roll()+die_2.roll()
    results.append(result)

frequencies = []
max_result=die_1.num_sides + die_2.num_sides
poss_results = range(2,max_result+1)
for value in poss_results:
        frequency=results.count(value)
        frequencies.append(frequency)

#对结果进行可视化

title="Results of Rolling a D6 and a D10 50,000 Times"
#大括号创建字典,键值对实现label的一一对应
labels={'x':'Result','y':'Frequency of Result'}
fig=px.bar(x=poss_results,y=frequencies,title=title,labels=labels)

#update_layout method进行进一步定制
fig.update_layout(xaxis_dtick=1)

#保存只需要把fig.show()替换掉就行了
fig.write_html('dice_visual_d6d10.html')

今天到此为止了,发现bug+debug真的挺费神费力的...真的是照着抄都能抄错哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值