Python學習之路14-生成資料

VPointer發表於2019-03-02

《Python程式設計:從入門到實踐》筆記。

從本篇起將用三篇的篇幅介紹如何用Python進行資料視覺化。

1. 前言

從本篇開始,我們將用三篇的篇幅來初步介紹如何使用Python來進行資料視覺化操作。本篇的內容包括:

  • 繪製簡單的折線圖;
  • 隨機漫步;
  • 使用Pygal模擬擲骰子。

在正式開始之前,需要安裝兩個擴充套件包:matplotlibpygal。Python中安裝第三方庫的方式已在上一個專案中介紹過了,這裡不再贅述。

2. 繪製簡單的折線圖

2.1 簡單的折線圖

首先我們繪製一個簡單的折線圖,程式碼儲存到mpl_squares.py檔案中:

import matplotlib.pyplot as plt

# 輸入資料, x軸
input_values = [1, 2, 3, 4, 5]
# 輸出資料, y軸
squares = [1, 4, 9, 16, 25]
# linewidth表示線條的粗細
plt.plot(input_values, squares, linewidth=5)

# 設定圖示標題,並給座標軸加上標籤
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)

# 設定刻度標記的大小
plt.tick_params(axis="both", labelsize=14)

plt.show()
複製程式碼

matplotlib.pyplot.plot()函式可以只傳入一個squares引數,表示y軸的值,此時將從x軸0點處開始一一對應。有時這樣很簡便,但在此例中圖示將不正確,所以我們傳入了input_values列表,將其與squares列表一一對應。

程式碼從第10行到15行都可以省了,這些程式碼只是讓圖表的資訊更全。最終的結果如下:

Python學習之路14-生成資料

2.2 生成散點圖

我們使用matplotlib.pyplot中的scatter()函式來生成散點圖,將程式碼儲存到scatter_squares.py檔案中:

import matplotlib.pyplot as plt

x_values = list(range(1, 1001))
y_values = [x ** 2 for x in x_values]

# s表示點的大小,edgecolor表示點的輪廓的顏色,c表示資料點的顏色(可以使用RGB顏色)
# plt.scatter(x_values, y_values, s=4, edgecolor="none", c="red")

# 使用漸變色, 給c賦值了一個y值列表,並使用引數cmap告訴pylot使用哪個顏色來對映
plt.scatter(x_values, y_values, s=40, edgecolor="none", c=y_values, cmap=plt.cm.Blues)

# 設定圖表標題並給座標軸加上標籤
plt.title("Square Number", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)

# 設定刻度的大小
plt.tick_params(axis="both", which="major", labelsize=14)

# 每個座標軸的取值範圍
plt.axis([0, 1100, 0, 1100000])

# 第一個引數是路徑名,第二個引數指定將圖表多餘的空白區域裁減掉。
plt.savefig("squares.png", bbox_inches="tight")

plt.show()
複製程式碼

我們使用了列表生成式來生成y軸的資料,並使用漸變色來繪製影像,matplotlib.pyplot.cm.Bluesmatplotlib自帶的漸變色,它和c的每一個值對應。通過pyplotaxis()函式來設定每個軸的取值範圍。最後將影像儲存到本地。生成的影像如下:

Python學習之路14-生成資料

3. 隨機漫步

隨機漫步指的是:每次行走都完全隨機,沒有明確的方向,結果是由一系列隨機決策決定的。在自然界、物理學、生物學、化學和經濟領域,隨機漫步都有其實際用途。

使用Python生成隨機漫步資料,再使用matplotlib將這些資料繪製出來。首先建立RandomWalk類,程式碼儲存到random_walk.py檔案中:

from random import choice

class RandomWalk:
    """一個生成隨機漫步資料的類"""

    def __init__(self, num_points=5000):
        """初始化隨機漫步的屬性"""
        self.num_points = num_points

        # 所有隨機漫步都始於(0, 0),這兩個列表用於儲存隨機漫步資料
        self.x_values = [0]
        self.y_values = [0]

    def fill_walk(self):
        """計算隨機漫步包含的所有點"""

        # 不斷漫步,直到列表到達指定的長度
        while len(self.x_values) < self.num_points:
            # 決定前進方向以及沿這個方向前進的距離
            # 通過choice從給定值中隨機選取
            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

            # 計算下一個點的座標
            next_x = self.x_values[-1] + x_step
            next_y = self.y_values[-1] + y_step

            self.x_values.append(next_x)
            self.y_values.append(next_y)
複製程式碼

下面的程式碼用於生成隨機漫步影像,程式碼儲存到rw_visual.py檔案中:

import matplotlib.pyplot as plt
from random_walk import RandomWalk

while True:
    rw = RandomWalk(50000)
    rw.fill_walk()

    # 設定繪圖視窗的尺寸
    plt.figure(figsize=(10, 6))

    # 繪製隨機漫步的影像
    point_number = list(range(rw.num_points))
    plt.scatter(rw.x_values, rw.y_values, s=1, c=point_number,
                edgecolors="none", cmap=plt.cm.Blues)

    # 突出起點和終點
    plt.scatter(0, 0, c="green", edgecolors="none", s=100)
    plt.scatter(rw.x_values[-1], rw.y_values[-1], c="red", edgecolors="none",
                s=100)

    # 隱藏座標軸
    plt.axes().get_xaxis().set_visible(False)
    plt.axes().get_yaxis().set_visible(False)

    plt.show()

    if input("Make another walk?(y/n)") == "n":
        break
複製程式碼

程式通過一個迴圈類多次繪製隨機漫步圖;通過pyplotfigure()函式來設定影像的尺寸,figsize的單位是英寸;通過漸變色來繪製影像的路徑,顏色由淺到深,並且我們將起點(綠色)和終點(紅色)顯著標出;最後隱藏座標軸。最終的影像如下(每次執行的效果都不同):

Python學習之路14-生成資料

4. 使用Pygal模擬擲骰子

首先我們需要建立一個骰子類Dice,將其儲存到dice.py中:

from random import randint

class Dice:
    """表示一個骰子類"""
    def __init__(self, num_sides=6):
        """骰子預設為6面"""
        self.num_sides = num_sides

    def roll(self):
        """返回一個位於1和骰子面數之間的隨機值"""
        return randint(1, self.num_sides)
複製程式碼

可以自行設定骰子的面數。下面是擲兩個骰子50000次,統計倆骰子點數之和的分佈的模擬,最後生成了一個向量檔案.svg檔案,它能在瀏覽器中開啟,程式碼如下:

import pygal
from dice import Dice

dice_1 = Dice()
dice_2 = Dice(10)

# 擲骰子多次,並將結果儲存在一個列表中
results = []
for roll_num in range(50000):
    results.append(dice_1.roll() + dice_2.roll())

# 分析結果
frequences = []
# 能夠模擬擲任何雙骰子的情況,不管這些骰子有多少面
max_result = dice_1.num_sides + dice_2.num_sides
for value in range(2, max_result + 1):
    # 統計每個結果的頻數
    frequences.append(results.count(value))

# 對結果進行視覺化
# 建立條形圖
hist = pygal.Bar()

hist.title = "Result of rolling a D6 and a D10 50000 times."
# 建立x軸上的刻度
hist.x_labels = [str(value) for value in range(2, max_result + 1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

# 給這組資料起個名字,並加到圖表中
hist.add("D6 + D10", frequences)
# 將影像渲染為svg檔案,向量圖
hist.render_to_file("dice_visual.svg")
複製程式碼

注意,frequences中的資料依次與hist.x_labels對應。下面是最終結果:

Python學習之路14-生成資料

Pygal讓這個圖表具有互動性:如果你將滑鼠指向該圖中的任何資料條,將看到它的具體資料。

5. 小結

本篇主要講述了:

  • 如何生成資料集以及如何對其進行視覺化;
  • 如何使用matplotlib建立簡單的圖表;
  • 如果使用散點圖來探索隨機漫步過程;
  • 如何使用Pygal建立直方圖,以及如何使用直方圖來探索同時擲兩個面數不同的骰子的結果。

迎大家關注我的微信公眾號”程式碼港” & 個人網站 www.vpointer.net ~

Python學習之路14-生成資料

相關文章