第五章 數據可視化
5.1 二維繪圖
5.1.1 一維數據集
生成20個標準正態分佈(僞)隨機數,保存在Numpy ndarray中。
'''
生成20個標準正態分佈(僞)隨機數,保存在Numpy ndarray中。
'''
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
np.random.seed(1000)
y = np.random.standard_normal(20)
x = range(len(y))
plt.plot(x, y)
plt.show()
plot會注意何時傳遞ndarray對象,此時沒必要單獨提供x值信息,只需要提供y值,plot就會以索引值作爲對應的x值。如下:
'''
生成20個標準正態分佈(僞)隨機數,保存在Numpy ndarray中。
'''
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
np.random.seed(1000)
y = np.random.standard_normal(20)
plt.plot(y)
plt.show()
通過調用ndarray對象上的cumsum方法,可以獲得這些數據的總和。
# 通過調用ndarray對象上的cumsum方法,可以獲得這些數據的總和
plt.plot(y.cumsum())
plt.show()
默認繪圖樣式不能滿足報表,一般都需要自定義樣式。可以修改軸的範圍,添加網格等,
# 上述默認繪圖樣式不能滿足報表,一般都需要自定義樣式。
plt.plot(y.cumsum())
plt.grid(True) # 添加網格
plt.axis('tight') # 修改軸範圍,tight使所有數據可見
plt.show()
設置座標軸的最小值最大值範圍,通過xlim,ylim進行設置
# 可以設置座標軸的最小值和最大值
plt.plot(y.cumsum())
plt.grid(True)
plt.xlim(-1, 20)
plt.ylim(np.min(y.cumsum()) - 1,
np.max(y.cumsum()) + 1)
plt.show()
爲了讓圖表更容易理解,可以添加附加的信息。
# 爲了讓圖標更容易理解,需要加些附加的信息
plt.figure(figsize=(7, 4))
plt.plot(y.cumsum(), 'b', lw=1.5) # 線寬1.5,藍色直線
plt.plot(y.cumsum(), 'ro') # 紅色圓點
plt.grid(True)
plt.axis('tight')
plt.xlabel('index') # x軸標識
plt.ylabel('value') # y軸標識
plt.title('A Simple Plot') # 標題
plt.show()
這裏顏色的縮寫如下:
字符 | 顏色 |
b | 藍色 |
g | 綠色 |
r | 紅色 |
c | 青色 |
m | 品紅 |
y |
黃色 |
k | 黑色 |
w | 白色 |
字符 | 象徵 |
- | 實線 |
-- | 短虛線 |
-. | 點實線 |
: | 虛線 |
. | 點標記 |
, | 像素標識 |
O | 圓標記 |
v | 向下三角形標記 |
^ | 向上三角形標記 |
< | 向左三角形標記 |
> | 想右三角形標記 |
1 | Tri_down標記 |
2 | Tri_up標記 |
3 | Tri_left標記 |
4 | Tri_right標記 |
s | 方形標記 |
p | 五邊形標記 |
* |
星號 |
h | 六角形標記1 |
H | 六角形標記2 |
+ | 加號 |
x | X標記 |
D | 菱形標記 |
d | 細菱形標記 |
| | 垂直標記 |
5.1.1 二維數據集
生成包含標準正態分佈(僞)隨機數的20x2Numpy ndarray。在這個數組上調用cumsum計算樣本數據在0軸(第一維上)的總和。
# 二維數據集
# 生成標準正態分佈僞隨機數的20x2的Numpy ndarray
np.random.seed(2000)
y = np.random.standard_normal((20, 2)).cumsum(axis=0)
# 一般來說,將這樣的二維數組傳遞給plt.plot,將自動把包含的數據解釋爲單獨的數據集(沿着1軸,即第二維
plt.figure(figsize=(7, 4))
plt.plot(y, lw=1.5)
plt.plot(y, 'ro')
plt.grid(True)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
plt.show()
在上述圖表中,多個圖表的集合,很難區分出單獨的一條曲線,這時候需要使用legend進行區分。plt.legend接受不同的位置參數。0表示最佳位置,也就是儘可能的少覆蓋數據。下述代碼中沒有傳遞整個ndarray對象,而是分別訪問y集合中的兩個數據子集y[:,0]和y[:,0]
# 使用legend區分不同的曲線
np.random.seed(2000)
y = np.random.standard_normal((20, 2)).cumsum(axis=0)
plt.figure(figsize=(7, 4))
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 1], lw=1.5, label='2nd')
plt.plot(y, 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
plt.show()
位置選項 | 描述 |
空白 | 自動 |
0 | 最佳 |
1 | 右上 |
2 | 左上 |
3 | 左下 |
4 | 右下 |
5 | 右 |
6 | 中左 |
7 | 中右 |
8 | 中下 |
9 | 中上 |
10 | 中 |
面對上述多條曲線的圖表,往往會出現不同圖表的y軸值在不同的範圍內,這時需要設置兩個不同的y軸範圍,而不是單一的y軸刻度。
首先繪製錯誤不可取的圖表信息(將其中一個的y值範圍擴大100倍)。
# 錯誤示範,將其中一個的數據擴大100倍
np.random.seed(2000)
y = np.random.standard_normal((20, 2)).cumsum(axis=0)
y[:, 0] = y[:, 0] * 100
plt.figure(figsize=(7, 4))
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 1], lw=1.5, label='2nd')
plt.plot(y, 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
plt.show()
上述的2nd曲線,完全看不出細節,這是不可取的,可以做如下操作,使繪製圖表的細節看得更明顯直觀。
# 這裏有兩種方式:使用2個軸; 使用兩個子圖
首先是使用兩個y軸
# 設置兩條y軸座標軸,避免丟失曲線細節可視化
# 這裏有兩種方式:使用2個軸; 使用兩個子圖
# 使用兩個y軸
np.random.seed(2000)
y = np.random.standard_normal((20, 2)).cumsum(axis=0)
y[:, 0] = y[:, 0] * 100
fig, ax1 = plt.subplots()
plt.plot(y[:, 0], 'b', lw=1.5, label='1st')
plt.plot(y[:, 0], 'ro')
plt.grid(True)
plt.legend(loc=8)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.title('A Simple Plot')
ax2 = ax1.twinx()
plt.plot(y[:, 1], 'g', lw=1.5, label='2nd')
plt.plot(y[:, 1], 'ro')
plt.legend(loc=0)
plt.ylabel('value 2nd')
plt.show()
管理座標軸的關鍵代碼如下:
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
使用plt.subplots函數,可以直接訪問底層繪圖對象。可以生成和第一個子圖共享x軸的第二個子圖。其實就是兩個完全重疊的子圖。
方法二:生成兩個單獨的子圖,這樣的數據集的自由度更大。
# 生成兩個單獨的子圖
np.random.seed(2000)
y = np.random.standard_normal((20, 2)).cumsum(axis=0)
y[:, 0] = y[:, 0] * 100
plt.figure(figsize=(7, 5))
plt.subplot(211)
plt.plot(y[:, 0], lw=1.5, label='1st')
plt.plot(y[:, 0], 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.ylabel('value')
plt.title('A Simple Plot')
plt.subplot(212)
plt.plot(y[:, 1], 'g', lw=1.5, label='2nd')
plt.plot(y[:, 1], 'ro')
plt.grid(True)
plt.legend(loc=0)
plt.axis('tight')
plt.xlabel('index')
plt.ylabel('value')
plt.show()
這裏,figure對象中子圖的定位是通過使用一種特殊的座標系來實現的。plt.subplot有三個整數參數,numrows,numcols和fignum(可由逗號或者不加逗號)
numrows:指定行數 numcols:指定列數 fignum:指定子圖編號(從1到 numrowsXnumcols)
例如繪製9個完全大小相等的子圖圖標,有numrows=3,numcols=3,fignum=1,2,3,...9,右下角的子圖座標爲plt.subplot(3,3,9)或者plt.subplot(339)。
有時候,需要用兩種不同形式的圖表類型來可視化數據,此時需要自由得組合matplotlib提供的任意圖標類型。
例:繪製線圖/點圖和柱狀圖: