第十五章 生成数据

生成数据

本文与课本稍有出入,本文采用的工具是pycharm,与课本稍有出入

15.1 安装Matplotlib

  1. win + R ,并输入 cmd , 进入命令行界面
    如下图:
    第十五章 生成数据
  2. 按提示信息,将 pip 版本升级至最新
    如下图:
    第十五章 生成数据
  3. 升级成功后, 使用 python -m pip install matplotlib 安装Matplotlib
    如下图:
    第十五章 生成数据
  4. 安装成功后,再次使用 python -m pip list ,发现matpoltlib已经存在了
    如下图:
    第十五章 生成数据
  5. 打开pycharm,新建一个项目:date_study
    如下图:
    第十五章 生成数据
  6. 新建一个测试文件:test.py,将以下代码复制进去,然后运行
import matplotlib.pyplot as plt
labels='frogs','hogs','dogs','logs'
sizes=15,20,45,10
colors='yellowgreen','gold','lightskyblue','lightcoral'
explode=0,0.1,0,0
plt.pie(sizes,explode=explode,labels=labels,colors=colors,autopct='%1.1f%%',shadow=True,startangle=50)
plt.show()

运行结果如下图:

第十五章 生成数据

15.2 绘制简单的折线图

  1. subplots()函数
  2. plot()函数
  3. show()函数

新建 test.py,输入以下代码

import matplotlib.pyplot as plt

squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(squares)

plt.show()

实现效果如下图:

第十五章 生成数据

15.2.1 修改标签文字和线条粗细

  1. set_title()
  2. set_xlabel()
  3. set_ylabel()
  4. tick_params()

改善图表的可读性

import matplotlib.pyplot as plt

squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(squares, linewidth=3)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平法数", fontsize=14)

ax.tick_params(axis="both", labelsize=14)

plt.show()

此时,运行程序,大概率会出现中文不能显示的情况,可以遵循以下方法解决

  1. Win + R ,输入 cmd 打开命令行窗口
  2. 输入 python,进入python界面
  3. 输入 import matplotlib 导入该模块
  4. 输入 matplotlib.matplotlib_fname() 查找该文件路径,查询结果为:
    C:\Users\zhangxy\AppData\Roaming\Python\Python39\site-packages\matplotlib\mpl-data\matplotlibrc
    (”\”需要改为”\”)
    5 .用文本方式打开该文件,搜索 font.family ,找到 # font.family: sans-serif ,将其改为
    font.family: Microsoft YaHei

此时运行程序,即可达到与课本相同的效果,如图:

第十五章 生成数据

15.2.2 校正图形

我们发现图形的终点4.0的平方是25,这很明显不对,这是因为:没有输入值时,假设的第一个x数据点是0,我们修复这个问题

import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(input_values, squares, linewidth=3)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平法数", fontsize=14)

ax.tick_params(axis="both", labelsize=14)

plt.show()

此时输出的图形是正确的,如下图:

第十五章 生成数据

15.2.3 使用内置样式

matplotlib提供了很多样式
执行程序

import matplotlib.pyplot as plt

print(plt.style.available)

输出:
[‘Solarize_Light2’, ‘_classic_test_patch’, ‘_mpl-gallery’, ‘_mpl-gallery-nogrid’, ‘bmh’, ‘classic’, ‘dark_background’, ‘fast’, ‘fivethirtyeight’, ‘ggplot’, ‘grayscale’, ‘seaborn’, ‘seaborn-bright’, ‘seaborn-colorblind’, ‘seaborn-dark’, ‘seaborn-dark-palette’, ‘seaborn-darkgrid’, ‘seaborn-deep’, ‘seaborn-muted’, ‘seaborn-notebook’, ‘seaborn-paper’, ‘seaborn-pastel’, ‘seaborn-poster’, ‘seaborn-talk’, ‘seaborn-ticks’, ‘seaborn-white’, ‘seaborn-whitegrid’, ‘tableau-colorblind10’]

使用其中的某一个样式,如:Solarize_Light2

使用 seaborn 又会出现汉语无法显示的问题

实现代码如下:

import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]

plt.style.use("Solarize_Light2")
fig, ax = plt.subplots()
ax.plot(input_values, squares, linewidth=3)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平法数", fontsize=14)

ax.tick_params(axis="both", labelsize=14)

plt.show()

执行程序,显示如下图:

第十五章 生成数据

15.2.4 使用scatter()绘制散点图并设置样式

绘制单个点,使用scatter()方法

import matplotlib.pyplot as plt

plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()
ax.scatter(2, 4)

plt.show()

执行结果如下图:

第十五章 生成数据

设置图标的样式,包括标题、坐标轴标签等

import matplotlib.pyplot as plt

plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()
ax.scatter(2, 4, s=200)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)

ax.tick_params(axis='both', which='major',labelsize=14)

plt.show()

执行结果如下图”:

第十五章 生成数据

15.2.5 使用scatter()绘制一系列点

要绘制一系列点,可以传递两个包含x,y的列表,列表值按下标组合成元素点坐标
x=[1,2,3];y=[4,5,6],那么点就是(1,4)、(2,5)、(3,6)三个

程序如下图:

import matplotlib.pyplot as plt

x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()
ax.scatter(x_values, y_values, s=100)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)

ax.tick_params(axis='both', which='major',labelsize=14)

plt.show()

执行结果如下图:

第十五章 生成数据

15.2.6 自动计算数据

如果数据量大,手动输入值效率低下,我们可以用python循环来完成


import matplotlib.pyplot as plt

x_values = range(1,1001)
y_values = [x**2 for x in x_values]
plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()
ax.scatter(x_values, y_values, s=10)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)

ax.tick_params(axis='both', which='major',labelsize=14)

ax.axis = ([0, 1100, 0, 1100000])

plt.show()

执行效果如下图:

第十五章 生成数据

15.2.7 自定义颜色

要修改数据点的颜色,只需要向scatter()传递参数c即可

c 可以是颜色的名称,如 c=’red’,也可以是RGB颜色,如 c=(0,0.8,0),三个值分别代表红、绿、蓝的分量,取值范围都是0-1


import matplotlib.pyplot as plt

x_values = range(1,1001)
y_values = [x**2 for x in x_values]
plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()

ax.scatter(x_values, y_values, c=(0, 0.8, 0), s=10)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)

ax.tick_params(axis='both', which='major',labelsize=14)

ax.axis = ([0, 1100, 0, 1100000])

plt.show()

执行结果如下图:

第十五章 生成数据

15.2.8 使用颜色映射

颜色映射首先将scatter()方法中的c设置为一个列表,然后用cmap参数进行颜色映射,小的值为浅色,大的值为深色


import matplotlib.pyplot as plt

x_values = range(1,1001)
y_values = [x**2 for x in x_values]
plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()

ax.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=10)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)

ax.tick_params(axis='both', which='major',labelsize=14)

ax.axis = ([0, 1100, 0, 1100000])

plt.show()

执行效果如下图:

第十五章 生成数据

15.2.9 自动保存图标

只需将plt.show()改为调用plt.savefig()


import matplotlib.pyplot as plt

x_values = range(1,1001)
y_values = [x**2 for x in x_values]
plt.style.use('Solarize_Light2')
fig, ax = plt.subplots()

ax.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=10)

ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)

ax.tick_params(axis='both', which='major',labelsize=14)

ax.axis = ([0, 1100, 0, 1100000])

plt.savefig('squares_plot.png', bbox_inches='tight')

执行程序,发现.py同目录下多了一个Png文件,如下图一:

第十五章 生成数据

打开该图片:

第十五章 生成数据

15.3 随机漫步

随机漫步指每次行走都是完全随机的,没有明确的方向,没有明确的步数

15.3.1 创建RandomWalk类 & 15.3.2 选择方向

RandomWalk类应该包括三个属性:

  1. 随机漫步的次数
  2. 随机漫步每次的x坐标
  3. 随机漫步每次的y坐标

x,y坐标合起来就是一个点

RandomWalk类还有2个方法:

  1. 初始化方法
  2. fill_walk()方法,该方法用来计算随机漫步经过的所有点

from random import choice

class RandomWalk:
    '''一个生成随机漫步的类'''

    def __init__(self, num_points=5000):
        '''初始化随机漫步的属性'''
        self.num_points = num_points

        self.x_values = [0]
        self.y_values = [0]

    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_distance * x_direction

            y_direction = choice([1, -1])
            y_distance = choice([0, 1, 2, 3, 4])
            y_step = y_distance * y_direction

            if x_step == 0 and y_step == 0:
                continue

            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.3.3 绘制随机漫步图

代码如下:


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

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.3.4 模拟多次随机漫步

使用while循环,实现多次随机漫步,只需修改rw.py代码:


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

while True:

    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()

    keep_running = input("Make another walk?(y/n): ")
    if keep_running == 'n':
        break

执行效果如图:

第十五章 生成数据

15.3.5 设置随机漫步图的样式

1 给着色点

本小节我们完成的任务是按照漫步的先后顺序给生成点着色,并去掉每个生成点 的外圈
修改rw.py的代码


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

while True:

    rw = RandomWalk()
    rw.fill_walk()

    plt.style.use('classic')
    fig, ax = plt.subplots()
    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)

    plt.show()

    keep_running = input("Make another walk?(y/n): ")
    if keep_running == 'n':
        break

文中说range()生成一个数字列表,我认为不妥,应该是一个可迭代对象,因为执行 range(100),生成的是 range(0,100)这个对象,不是列表

执行结果如下图:

第十五章 生成数据

2 重新绘制起点和终点

本小节的工作是将起点和终点突出显示
修改rw.py代码


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

while True:

    rw = RandomWalk()
    rw.fill_walk()

    plt.style.use('classic')
    fig, ax = plt.subplots()
    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)

    ax.scatter(0, 0, c='green', edgecolor='none', s=100)
    ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolor='none', s=100)

    plt.show()

    keep_running = input("Make another walk?(y/n): ")
    if keep_running == 'n':
        break

执行结果如下图:

第十五章 生成数据

3 隐藏坐标轴

修改rw.py代码,隐藏坐标轴


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

while True:

    rw = RandomWalk()
    rw.fill_walk()

    plt.style.use('classic')
    fig, ax = plt.subplots()
    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)

    ax.scatter(0, 0, c='green', edgecolor='none', s=100)
    ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolor='none', s=100)

    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    plt.show()

    keep_running = input("Make another walk?(y/n): ")
    if keep_running == 'n':
        break

执行后,如图:

第十五章 生成数据

4 增加点数

增加随机漫步的点数,只需在生成对象时传递一个较大的实参即可


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

while True:

    rw = RandomWalk(50000)
    rw.fill_walk()

    plt.style.use('classic')
    fig, ax = plt.subplots()
    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)

    ax.scatter(0, 0, c='green', edgecolor='none', s=100)
    ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolor='none', s=100)

    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    plt.show()

    keep_running = input("Make another walk?(y/n): ")
    if keep_running == 'n':
        break

执行结果如下图:

第十五章 生成数据

5 调整尺寸已适合屏幕

调整屏幕显示尺寸,需要调整plt.subplots()的参数
参数figsize=(10,6)表示在10X6英寸的屏幕上显示
参数dpi 默认值是100,表示分辨率
修改rw.py的代码,将生成实例时的实参去掉,还是按5000个点生成


import matplotlib.pyplot as plt
from randomwalk import RandomWalk

while True:

    rw = RandomWalk()
    rw.fill_walk()

    plt.style.use('classic')
    fig, ax = plt.subplots(figsize=(10,6), dpi=128)
    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)

    ax.scatter(0, 0, c='green', edgecolor='none', s=100)
    ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolor='none', s=100)

    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    plt.show()

    keep_running = input("Make another walk?(y/n): ")
    if keep_running == 'n':
        break

执行程序后,显示如下图:

第十五章 生成数据

15.4 使用 Plotly 模拟掷色子

如果掷一个色子,出现1-6的几率时持平的,但是如果同时投掷两个色子,出现某些点数的可能性就会高,Plotly是一个python包,可以将数据绘成可交互图形

15.4.1 安装Plotly

Plotly 安装包安装速度很慢,使用 python -m install plotly 都会因为超时而失败
但如果使用镜像,命令为 python -m pip install http://pypi.douban.com/simple/ plotly 会出现无法解压的错误

以下是亲测有效的安装方法:

  1. win + r 输入 cmd 打开命令行窗口
  2. 输入 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple –trusted-host pypi.tuna.tsinghua.edu.cn plotly
  3. 安装成功后 输入 python -> import plotly -> plotly.__ version__验证是否安装成功

如下图所示:

第十五章 生成数据

; 15.4.2 创建Die 类

创建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-6的随机数'''
        return randint(1, self.num_sides)

15.4.3 掷色子

创建一个实例,验证创建的类是否合理
在die_visual.py中编写代码


from die import Die

die = Die()

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

print(results)

掷色子10次,发现结果符合预期
如下图:

第十五章 生成数据

15.4.4 分析结果

掷1000次色子,计算每个点数出现的次数,并将出现的次数存在一个列表中
直接修改 die_visual.py的代码


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,die.num_sides+1):
    frequency = results.count(value)
    frequencies.append(frequency)

print(frequencies)

执行结果:
[162, 160, 177, 153, 182, 166]

15.4.5 绘制直方图

修改 die_visual.py文件


from plotly.graph_objs import Bar, Layout
from plotly import offline

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,die.num_sides+1):
    frequency = results.count(value)
    frequencies.append(frequency)

x_values = list(range(1,die.num_sides+1))
data =[Bar(x=x_values, y=frequencies)]

x_axis_config ={'title': '结果'}
y_axis_config ={'title': '结果的频率'}

my_layout = Layout(title='掷一个D6色子 1000次的结果', xaxis=x_axis_config, yaxis=y_axis_config)

offline.plot({'data': data, 'layout': my_layout}, filename='d6.html')

执行程序,在浏览器生成一个直方图。见下图:

第十五章 生成数据

15.4.6 同时掷两个色子

同时掷两个色子,则横坐标数据就变为两个色子点数相加,结果仍然存在results列表中
重新创建一个dice_visual.py文件,将die_visual.py文件代码复制过来, 然后进行修改


from plotly.graph_objs import Bar, Layout
from plotly import offline

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

x_values = list(range(2,max_result+1))
data =[Bar(x=x_values, y=frequencies)]

x_axis_config ={'title': '结果', 'dtick': 1}
y_axis_config ={'title': '结果的频率'}

my_layout = Layout(title='掷2个D6色子 1000次的结果', xaxis=x_axis_config, yaxis=y_axis_config)

offline.plot({'data': data, 'layout': my_layout}, filename='d6_d6.html')

程序执行如下图:

第十五章 生成数据

15.4.7 同时掷两个面数不同的色子

同时掷一个6面和一个10面的色子,一共掷5000次,结果会如何?
新建一个dice_6_10_visual.py 文件,将dice_visual.py代码复制过来进行修改


from plotly.graph_objs import Bar, Layout
from plotly import offline

from die import Die

die_1 = Die()
die_2 = Die(10)

results = []
for roll_num in range(5000):
    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)

x_values = list(range(2,max_result+1))
data =[Bar(x=x_values, y=frequencies)]

x_axis_config ={'title': '结果', 'dtick': 1}
y_axis_config ={'title': '结果的频率'}

my_layout = Layout(title='掷1个D6和1个D10色子 5000次的结果', xaxis=x_axis_config, yaxis=y_axis_config)

offline.plot({'data': data, 'layout': my_layout}, filename='d6_d10.html')

程序执行结果如下图:

第十五章 生成数据

15.5 小结

Original: https://blog.csdn.net/lemogate/article/details/122753111
Author: ChaseTimLee
Title: 第十五章 生成数据

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/767338/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球