《Python程式設計:從入門到實踐》筆記。
從本篇起將用三篇的篇幅介紹如何用Python進行資料視覺化。
1. 前言
從本篇開始,我們將用三篇的篇幅來初步介紹如何使用Python來進行資料視覺化操作。本篇的內容包括:
- 繪製簡單的折線圖;
- 隨機漫步;
- 使用
Pygal
模擬擲骰子。
在正式開始之前,需要安裝兩個擴充套件包:matplotlib
和pygal
。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行都可以省了,這些程式碼只是讓圖表的資訊更全。最終的結果如下:
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.Blues
是matplotlib
自帶的漸變色,它和c
的每一個值對應。通過pyplot
的axis()
函式來設定每個軸的取值範圍。最後將影像儲存到本地。生成的影像如下:
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
複製程式碼
程式通過一個迴圈類多次繪製隨機漫步圖;通過pyplot
的figure()
函式來設定影像的尺寸,figsize
的單位是英寸;通過漸變色來繪製影像的路徑,顏色由淺到深,並且我們將起點(綠色)和終點(紅色)顯著標出;最後隱藏座標軸。最終的影像如下(每次執行的效果都不同):
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
對應。下面是最終結果:
Pygal
讓這個圖表具有互動性:如果你將滑鼠指向該圖中的任何資料條,將看到它的具體資料。
5. 小結
本篇主要講述了:
- 如何生成資料集以及如何對其進行視覺化;
- 如何使用
matplotlib
建立簡單的圖表; - 如果使用散點圖來探索隨機漫步過程;
- 如何使用
Pygal
建立直方圖,以及如何使用直方圖來探索同時擲兩個面數不同的骰子的結果。
迎大家關注我的微信公眾號”程式碼港” & 個人網站 www.vpointer.net ~