前沿
Python提供了很多模塊用於數據可視化,其中matplotlib、pygal等模塊。我參考網上熱門書籍《Python編程從入門到實戰》,在測試與學習過程中遇到的些許問題加以解決,才寫下這一項目實戰的心得,對於Python基礎部分就不細講,主要是項目核心要點和解決方案的描述。本小節先講述pyplot模塊的基本使用。
新手的建議
針對新手,真心覺得不要直接使用Python下載來的IDLE來開發,因爲功能太少了,也不好使用。我的建議是對於Python初學者,先安裝Anaconda,這是一個基於Python的數據處理和科學計算平臺,它已經內置了許多非常有用的第三方庫,我們裝上Anaconda,就相當於把數十個第三方模塊自動安裝好了,非常簡單易用,在安裝界面添加Anaconda到PATH環境變量中勾上,這樣就會自動添加環境變量了。Anaconda 自帶了一個編輯器-Spyder,可以使用Spyder編寫代碼,知道有這個編輯器就好。然後再安裝一個PyCharm,它是一種Python IDE,帶有一整套可以幫助用戶在使用Python語言開發時提高其效率的工具。
Anaconda和PyCharm安裝過程和方法文檔鏈接,我是摘抄網上有用的資料再總結出來的:鏈接:https://pan.baidu.com/s/10KcfLLvI9omIRSJ6JMK9Uw 密碼:cgf8
利用pyplot模塊的plot函數繪製折線圖
我們先導入模塊pyplot,然後使用該模塊的plot函數來繪製折線圖,接着調用該模塊的相關函數來調整、設置圖表的標題、橫縱標籤、刻度標記內容或大小。注意, pyplot模塊的plot函數可以接收輸入參數和輸出參數,還有線條粗細等參數,但是若plot函數只指定輸出參數(列表),那麼輸入參數默認由0開始。
(1)plot函數指定輸出參數(1,2,3,4,5的平方數列表)
import matplotlib.pyplot as plt
# pyplot模塊的plot函數可以接收輸入參數和輸出參數,還有線條粗細等參數,,例如下方的示例
squares = [1, 4, 9, 16, 25]
plt.plot(squares, linewidth=5) # 這裏只指定了一個列表,那麼就當作是輸出參數,輸入參數從0開始,就會發現沒有正確繪製數據
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.tick_params(axis='both', labelsize=14) # 參數axis值爲both,代表要設置橫縱的刻度標記,標記大小爲14
plt.show() # 打開matplotlib查看器,並顯示繪製的圖形
運行結果如下:
(2)plot函數指定輸入參數和輸出參數
我們知道,上面並沒有按照我們的意願來繪製圖形,Y軸指定爲[1,4,9,16,25],上面採用默認輸入參數處理X軸變成[0,1,2,3,4]。X軸應該對應值爲[1,2,3,4,5]纔是我們的目的,所以我們必須同時指定輸入參數和輸出參數才行。觀察運行結果圖的X軸變化了。
import matplotlib.pyplot as plt
# 我也可以指定輸入參數和輸出參數,這樣就能按照我的意願繪製圖形了
input_values = [1, 2, 3, 4, 5] # 指定輸入參數
squares = [1, 4, 9, 16, 25] # 指定輸出參數
plt.plot(input_values, squares, linewidth=5) # 調用繪製函數,傳入輸入參數和輸出參數
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.tick_params(axis='both', labelsize=14) # 參數axis值爲both,代表要設置橫縱的刻度標記,標記大小爲14
plt.show() # 打開matplotlib查看器,並顯示繪製的圖形
運行結果如下:
利用pyplot模塊的scatter函數繪製散點圖
繪製散點圖只不過是繪製函數不同,從上面的plot變爲scatter,其他設置標題、橫縱標籤等的方式一樣。
(1)scatter函數繪製單個點
import matplotlib.pyplot as plt
plt.scatter(2, 4, s=200) # 傳遞一對x和y座標。它將在指定位置繪製一個點,參數s是設置繪製圖形時使用的點的尺寸
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.tick_params(axis='both', labelsize=14) # 參數axis值爲both,代表要設置橫縱的刻度標記,標記大小爲14
plt.show() # 打開matplotlib查看器,並顯示繪製的圖形
運行結果如下:
(2)scatter函數繪製一系列點
import matplotlib.pyplot as plt
x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
plt.scatter(x_values, y_values, s=100) # 傳入兩個列表,列表x_values的元素作爲x座標,列表y_values的元素作爲y座標,兩個組合成一個點的座標,所以一共有5個點
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.tick_params(axis='both', labelsize=14) # 參數axis值爲both,代表要設置橫縱的刻度標記,標記大小爲14
plt.show() # 打開matplotlib查看器,並顯示繪製的圖形
運行結果如下:
(3)自動計算Y軸的數據
前面個兩個實例挺簡單,但也只是我們自己定義的短列表,如果要繪製的點有很多,那麼還手動寫當然不實際,所以我們寫一個根據我們指定的X軸的數據,自動計算Y軸的數據就省事很多了。
import matplotlib.pyplot as plt
x_values = list(range(1, 1001)) # 我們是利用range函數生成一個從1到1000的可迭代對象(不包括1001),然後強制轉換爲列表
y_values = [x ** 2 for x in x_values] # 這個語法是列表推導式,將x_values每個元素的值進行平方再逐一放入列表,最後這個列表推導式返回整個列表
plt.scatter(x_values, y_values, s=40) # 在2.0.0版本後的matplotlib中,scatter()函數的實參edgecolor(數據點的輪廓)默認爲'none',則刪除輪廓。
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.axis([0, 1100, 0, 1100000]) # 設置每個座標軸的取值範圍。其實最右側就是1100,但是沒有顯示標籤而已
plt.show() # 打開matplotlib查看器,並顯示繪製的圖形
運行結果如下:
注意, 在2.0.0版本後的matplotlib中scatter()函數的實參edgecolor(數據點的輪廓)不寫則默認爲'none',代表刪除輪廓。也可以通過以下修改代碼:
plt.scatter(x_values, y_values, s=40, edgecolor='red')
上述修改後的代碼指定數據點輪廓的顏色爲紅色,由於默認點的顏色爲藍色,所以你將會看到下面這樣,只有右上角是藍色,其他都是紅色,這是因爲繪製很多點,紅色輪廓都粘連在一起了,所以看不出來。
修改代碼後運行結果如下:
上面說了默認數據點的顏色爲藍色,我們也可以通過參數c修改數據點的顏色,至於顏色值可以採用直接寫顏色英文如'red'、'black'等,或者使用RGB顏色模式自定義顏色,這個自定義顏色設置爲一個元組,其中包含三個0~1之間的小數值,它們分別表示紅色、綠色和藍色分量,如(0,0,0.8)。可以通過下面這樣修改代碼:
import matplotlib.pyplot as plt
x_values = list(range(1, 1001))
y_values = [x ** 2 for x in x_values]
plt.scatter(x_values, y_values, c=(0, 0.8, 0), s=40) # 指定了c參數,使用的是RGB顏色值方式
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.axis([0, 1100, 0, 1100000]) # 設置每個座標軸的取值範圍。其實最右側就是1100,但是沒有顯示標籤而已
plt.show() # 打開matplotlib查看器,並顯示繪製的圖形
運行結果如下:
(4)使用顏色映射和自動保存圖表
照書上P294頁的使用顏色映射小節的描述對於初學者可能有點模棱兩可,這裏採用我自己的代碼來理解什麼是顏色映射,原理是什麼。
測試代碼如下:
import matplotlib.pyplot as plt
x_values = [1, 2, 3, 4, 5] # 含x值的列表
y_values = [1, 4, 2, 6, 5] # 含y值的列表
# 我們知道根據上面兩個列表,我們調用scatter可以繪製一系列的點
# 模塊pyplot內置了一組顏色映射,通過設置c參數爲y列表的值(這個y列表的是[1,2,3,4,5])然後利用參數cmap根據y列表的大小映射到由x_values和y_values組成的五個點從淺到深的顏色,可以看出y列表[1,2,3,4,5]分別映射到(1,1),(2,4),(3,2),(4,6),(5,5)五個點,其中(1,1)點顏色最淺,(5,5)點顏色最深。
plt.scatter(x_values, y_values, c=[1, 2, 3, 4, 5], cmap=plt.cm.Blues, s=100)
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.savefig("3.png", bbox_inches='tight') # 打開matplotlib查看器,並顯示繪製的圖形
# 值的注意的是,要讓程序自動將圖表保存到文件中,可將對plt.show()的調用替換爲對plt.savefig()的調用。
# 如果指定了bbox_inches='tight'將圖表多餘的空白區域裁剪掉,明顯更符合用戶需求,如果沒指定,生成的圖片顯示不出Y軸的標籤。
運行結果如下(需要注意,其實(1,1)點的位置還有一個非常淺藍色的點,只是淺到看不到而已):
如果還不理解,那麼你就修改以下測試代碼來運行觀察:
plt.scatter(x_values, y_values, c=[1, 5, 3, 4, 5], cmap=plt.cm.Blues, s=100)
運行結果如下(可以發現(2,4)點的顏色也變成深藍色了哦):
有了上面的理解基礎,我們可以修改爲書本源代碼,來觀察一下藍色彗星的殘影,哈哈O(∩_∩)O
書本源代碼:
import matplotlib.pyplot as plt
x_values = list(range(1,1001)) # 含x值的列表
y_values = [x ** 2 for x in x_values] # 含y值的列表
# 我們知道根據上面兩個列表,我們調用scatter可以繪製一系列的點
# 根據y列表的值大小進行顏色映射的,值大的顏色深,值小的顏色淺。如果y列表的值按順序,並且映射到按順序的點,那麼自然顏色也是從淺到深。
# 模塊pyplot內置了一組顏色映射,通過設置c參數爲y列表的值(這個y列表的是[1,2,3,4,5])然後利用參數cmap根據y列表的大小映射到由x_values和y_values組成的五個點從淺到深的顏色,可以看出y列表[1,2,3,4,5]分別映射到(1,1),(2,4),(3,2),(4,6),(5,5)五個點,其中(1,1)點顏色最淺,(5,5)點顏色最深。
plt.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=40)
plt.title("Square Numbers", fontsize=24) # 指定標題,並設置標題字體大小
plt.xlabel("Value", fontsize=14) # 指定X座標軸的標籤,並設置標籤字體大小
plt.ylabel("Square of Value", fontsize=14) # 指定Y座標軸的標籤,並設置標籤字體大小
plt.savefig("3.png", bbox_inches='tight') # 打開matplotlib查看器,並顯示繪製的圖形
運行結果圖如下(藍色彗星殘影):
利用pyplot模塊的scatter函數繪製隨機漫步圖
套用書本原話來說,隨機漫步:每次行走都完全是隨機的,沒有明確的方向,結果是由一系列隨機決策決定的。
爲了實現隨機漫步,需要做以下幾步就可以完成:
1.創建RandomWalk類來生成隨機漫步數據
2.利用獲取的隨機漫步數據繪製隨機漫步圖
3.模擬多次隨機漫步
4.設置隨機漫步圖的樣式
(1)創建RandomWalk類來生成隨機漫步數據
在項目裏創建一個random_walk.py文件,該文件代碼如下:
from random import choice
# 一個生成隨機漫步數據的類
class RandomWalk:
# 默認爲5000個點,代表5000步
def __init__(self, num_points=5000):
self.num_points = num_points
self.x_values = [0]
self.y_values = [0]
# 獲取隨機方向和步數的乘積
def get_step(self):
return choice([1, -1]) * choice([0, 1, 2, 3, 4])
def fill_walk(self):
while len(self.x_values) < self.num_points:
# 獲取往哪個方向走幾步
x_step = self.get_step()
y_step = self.get_step()
# 如果原地踏步則continue處理
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)
(2)利用獲取的隨機漫步數據繪製隨機漫步圖
在項目裏創建一個rw_visual.py文件,該文件代碼如下:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 創建一個RandomWalk實例,並指定走5000步
rw = RandomWalk(5000)
rw.fill_walk() # 開始獲取隨機漫步數據,其實獲取的是兩個包含x和y值的數據點列表
plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()
運行結果如下:
(3)模擬多次隨機漫步
在rw_visual.py文件代碼上加以修改,修改代碼如下:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
while True:
rw = RandomWalk(5000)
rw.fill_walk()
plt.scatter(rw.x_values, rw.y_values,s=15)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
運行結果如下(你點擊右上角關閉按鈕,在PyCharm下方會彈出詢問是否繼續漫步):
(4)設置隨機漫步圖的樣式
我們將設置隨機漫步圖的樣式,定製一個好看的隨機漫步圖,有給點着色、重新繪製起點和終點、隱藏座標軸、調整尺寸以適合屏幕。
import matplotlib.pyplot as plt
from random_walk import RandomWalk
while True:
rw = RandomWalk(5000)
rw.fill_walk()
plt.figure(figsize=(20, 6))
# 顏色映射就是用列表賦值給c,而這個列表的值可以隨意,大的代表顏色深,小的代表顏色淺。
point_number = list(range(rw.num_points)) # [0-4999]
plt.scatter(rw.x_values, rw.y_values, c=point_number, cmap=plt.cm.Blues, s=4)
# 突出起點和終點,點變大,用不同顏色來顯示起點和終點
plt.scatter(0, 0, c='green', s=100)
plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', s=100)
# 隱藏座標軸
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
運行結果如下: