hi~~~ 我是宋宋,今天給大家分享的是數(shù)據(jù)分析的可視化部分。
### 簡(jiǎn)介
信息可視化(也叫繪圖)是數(shù)據(jù)分析中最重要的?作之?。它可能是探索過程的?部分,例如,幫助我們找出異常值、必要的數(shù)據(jù)轉(zhuǎn)換、得出有關(guān)模型的idea等。
其實(shí)做 Python的數(shù)據(jù)可視化,可以使用的庫分別是 Matplotlib 、Seaborn 、Bokeh、 Plotly 、Pyecharts等。
Matplotlib是Python數(shù)據(jù)可視化庫中的泰斗,它已經(jīng)成為python中公認(rèn)的數(shù)據(jù)可視化工具,通過Matplotlib可以很方便的設(shè)計(jì)和輸出二維以及三維的數(shù)據(jù),其提供了常規(guī)的笛卡爾坐標(biāo),極坐標(biāo),球坐標(biāo),三維坐標(biāo)等,其輸出的圖片質(zhì)量也達(dá)到了科技論文中的印刷質(zhì)量,日常的基本繪圖更不在話下。
Matplotlib 是一個(gè) Python 的 2D繪圖庫,通過 Matplotlib,開發(fā)者可以僅需要幾行代碼,便可以生成繪圖,直方圖,功率譜,條形圖,錯(cuò)誤圖,散點(diǎn)圖等。
優(yōu)勢(shì):
> (1)能將數(shù)據(jù)進(jìn)行可視化,更直觀的呈現(xiàn)
>
> (2)使數(shù)據(jù)更加客觀,更具說服力
在分享Matplotlib之前我們先了解以下幾個(gè)概念:
**畫板、畫紙的概念**
我們知道畫畫時(shí)需要畫板和畫紙。在matplotlib中也是一個(gè)道理。
圖形在畫板(figure)中繪制完成,而畫板又由不同的畫布(紙)(axes)構(gòu)成,具體的圖形構(gòu)建時(shí)要指明畫板和畫布,否則默認(rèn)一畫板一畫布。
##### 畫板(figure)
畫板存在的意義:
- 控制圖像的比例情況(大?。?br />- 保存圖像
創(chuàng)建一個(gè)畫板
> plt.figure(
> num=None, 用于指定在畫板上,放幾個(gè)畫布
> figsize=None, (寬度, 高度)
> dpi=None, 圖像的分辨率
> facecolor=None, 背景色
> edgecolor=None, 邊界顏色
> frameon=True,
> FigureClass,
> clear=False,
> **kwargs,
> linewidth
> )
##### 畫布(axes)
一個(gè)坐標(biāo)系就是一個(gè)畫布,就是一個(gè)圖,一個(gè)畫板上可以有多個(gè)坐標(biāo)系
畫布的創(chuàng)建
畫布要?jiǎng)?chuàng)建在畫板上
fig.add_subplot(nrows, ncols, index)
nrows將畫板分為幾行,ncols將畫板分為幾列,index選取使用哪一個(gè)被劃分的畫板
> add_subplot(nrows, ncols, index, \**kwargs)
> add_subplot(pos, **kwargs)
> add_subplot(ax)
> add_subplot()
畫板與畫布的關(guān)系
matplotlib圖標(biāo)的基本組成
- 畫板figure 呈現(xiàn)出來的坐標(biāo)系
- 繪圖區(qū)域axes 【畫布】
- x軸和y軸的水平垂直軸線 以及 軸標(biāo)簽
- 軸線上的刻度 以及 對(duì)應(yīng)的刻度標(biāo)簽
- 畫布標(biāo)題
- 圖例
### 如何使用繪圖包Matplotlib?
matplotlib的基本要素:
```
# 導(dǎo)入pyplot和matplotlib模塊
import matplotlib as mpl
from matplotlib import pyplot as plt
%matplotlib inline # 繪制的圖片在當(dāng)前文檔顯示
```
默認(rèn)一畫板一畫紙,我們也可以自己定義畫板figure和畫布axes,添加順序是:
> 1. 定義一個(gè)figure對(duì)象
> 2. 給figure對(duì)象添加subplot
比如:
```python
import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
%matplotlib inline
fig = plt.figure()
# 指定切分區(qū)域的位置
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)
random_arr = np.random.randn(100)
plt.plot(random_arr)
plt.show()
```
大家可以發(fā)現(xiàn)在最后一個(gè)畫布上顯示了圖像,但是前面三個(gè)沒有顯示出來,原因是此時(shí)的plt是有上下文的,所謂上下文就是在ax2和ax3之間使用plt.plot()進(jìn)行繪制則繪制的圖形是ax2這個(gè)畫紙的。即在哪個(gè)畫紙下面執(zhí)行畫圖就會(huì)繪制在誰上面,前提是下一個(gè)畫布創(chuàng)建之前。所以如果在ax2和ax4上畫圖也可以改成如下代碼,
```
import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
%matplotlib inline
fig = plt.figure()
random_arr = np.random.randn(100)
# 指定切分區(qū)域的位置
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
plt.plot(random_arr)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)
plt.plot(random_arr)
plt.show()
```
注意: 如果繪圖區(qū)域顯示的圖像比較小,可以結(jié)合參數(shù)figsize=(寬度,高度)進(jìn)行設(shè)定。
當(dāng)然也可以使用畫布axes對(duì)象進(jìn)行繪制,比如下面代碼:
```
# 省略導(dǎo)入,同上
...
fig = plt.figure(figsize=(11,7)) # 畫板的大小 設(shè)置的橫向和縱向的值 單位是英寸 可以表示水平和垂直的縮放
random_arr = np.random.randn(100)
# 指定切分區(qū)域的位置
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)
random_arr = np.random.randn(100)
ax1.plot(random_arr)
random_arr = np.random.randn(100)
ax2.plot(random_arr)
random_arr = np.random.randn(100)
ax3.plot(random_arr)
random_arr = np.random.randn(100)
ax4.plot(random_arr)
plt.show()
```
其中的add_subplot(self, *args, **kwargs) 表示向figure添加一個(gè)Axes作為一subplot布局的一部分。
add_subplot()方法本質(zhì)上做了兩件事:
1. 將整個(gè)Figure區(qū)域劃分為Row * col的網(wǎng)格;
2. 在網(wǎng)格的指定格子(索引號(hào))中創(chuàng)建一個(gè)Axes
add_subplot()網(wǎng)格有兩種定義方式:
第一種是用3個(gè)參數(shù),分別代表網(wǎng)格的,行數(shù) nrows, 列數(shù) ncols, 索引號(hào)index。它們都是位置參數(shù)。這種是第1種調(diào)用簽名形式。
第二種是用一個(gè)3位數(shù)的整數(shù),如,224,第一個(gè)2表示2行,第二個(gè)2表示2列,第3位上的4表示第4個(gè)格子。這就是第二種調(diào)用簽名形式,pos為224,也是位置參數(shù)。
比如說創(chuàng)建一個(gè)2行2列的布局,繪圖在第四個(gè)axes,注意:2*2的網(wǎng)格是虛擬的,起一個(gè)定位的作用
**小結(jié):**
1. figure就是一個(gè)矩形容器(頂層容器),可以再劃分為小方格,每個(gè)方格就是一個(gè)subplot,即子繪圖區(qū)。
2. 一個(gè)圖形中可以有多個(gè)subplot,這些subplot又可以被看作一個(gè)整體,有一些屬性如整個(gè)subplot的位置、內(nèi)部(單個(gè)subplot之間)的間距等,這些屬性保存在figure.SubplotParams類中??梢酝ㄟ^Figure的subplotpars參數(shù)來修改這些屬性。
3. 子圖使用了subplot,而不是subfigure。fiugre僅是一個(gè)矩形容器,而plot則是具體的圖形元素了,所以subplot會(huì)自動(dòng)創(chuàng)建一個(gè)Axes,這個(gè)Axes是屬于特定subplot的。
### 畫布的設(shè)置
創(chuàng)建好了畫布之后,我們就可以對(duì)畫布進(jìn)行設(shè)置,比如添加標(biāo)題、坐標(biāo)軸、設(shè)置坐標(biāo)軸刻度、圖例等
#### artist操作
**設(shè)置畫布標(biāo)題**
> axes.set_title(label)
> label,
> fontdict=None,
> loc=None,
> pad=None,
> *,
> y=None,
> **kwargs,
> )
> 可以設(shè)置標(biāo)題的位置,樣式
**設(shè)置坐標(biāo)軸標(biāo)簽**
> axes.set_xlabel()
> axes.set_ylabel(
> ylabel, # 坐標(biāo)軸標(biāo)簽名
> fontdict=None, # 字體大小
> labelpad=None,
> *,
> loc=None, # 位置{'left', 'center', 'right'}
> **kwargs,
>
> rotation, # 旋轉(zhuǎn)
> color, # 顏色
> )
**開啟和關(guān)閉坐標(biāo)軸**
> axes.set_axis_on()
> axes.set_axis_off()
**設(shè)置坐標(biāo)軸范圍【相當(dāng)于只看一部分】**
> axes.axis([xmin, xmax, ymin, ymax])
>
> axes.set_xlim(min,max)
> axes.set_ylim(min,max)
**設(shè)置坐標(biāo)軸刻度**
> axes.set_xticks([float, float])
> axes.set_yticks(
> ticks=[float, float], 刻度的位置會(huì)根據(jù)數(shù)據(jù)的范圍以及數(shù)據(jù)本身設(shè)置刻度的位置
> labels=['',''],
> rotation,
> fontsize,
> color
> )
**設(shè)置網(wǎng)格**
> axes.grid(b=None, which='major', axis='both', **kwargs)
> axes.grid(True
> )
**設(shè)置圖例**
在繪圖操作中設(shè)置label參數(shù),再調(diào)用圖例顯示方法
在圖例方法中傳入字符串列表
> axes.legend(handles, labels, loc)
> ** loc:圖例位置
> ** labels:圖例標(biāo)簽名稱
> ** handles:
> =============== =============
> Location String Location Code
> =============== =============
> 'best' 0
>
> 'upper right' 1
> 'upper left' 2
> 'lower left' 3
> 'lower right' 4
> 'right' 5
> 'center left' 6
> 'center right' 7
> 'lower center' 8
> 'upper center' 9
> 'center' 10
> =============== =============
案例:
```
fig = plt.figure(figsize=(10,5))
x = np.linspace(0, np.pi * 2, 100)
y = np.sin(x)
ax1 = fig.add_subplot(1,2,1)
ax1.set_title('正余弦波', fontsize=20, fontweight='bold', horizontalalignment='left', verticalalignment='bottom') # 默認(rèn)是不支持漢字的
ax1.plot(x, y)
ax1.plot(x, np.cos(x))
ax1.legend(['sin(x)', 'cos(x)'],loc='upper right')
ax2 = fig.add_subplot(1,2,2)
random_arr = np.random.randn(100)
ax2.plot(random_arr)
ax2.set_title('標(biāo)準(zhǔn)正態(tài)分布')
```
設(shè)置的標(biāo)題是中文的,因?yàn)橐胫С种形目梢蕴砑尤缦麓a在執(zhí)行之前:
```
plt.rcParams['font.sans-serif'] = ['Simhei']
# 中文情況下 負(fù)號(hào)顯示會(huì)有異常 所以還需要設(shè)置負(fù)號(hào)的操作
# 'axes.unicode_minus'
plt.rcParams['axes.unicode_minus'] = False
# 設(shè)置的是點(diǎn)的標(biāo)記 默認(rèn)是就是None 不顯示
plt.rcParams['lines.marker'] = 'None'
```
當(dāng)然上面的操作也可以在上下文上完成,結(jié)果是一樣的。只不過去掉了set_title()中的set_直接使用plt繪制。其他屬性也是一樣的。即:
```
fig = plt.figure(figsize=(10,5))
x = np.linspace(0, np.pi * 2, 100)
y = np.sin(x)
ax1 = fig.add_subplot(1,2,1)
plt.title('正余弦波', fontsize=20, fontweight='bold', horizontalalignment='left', verticalalignment='bottom') # 默認(rèn)是不支持漢字的
plt.plot(x, y)
plt.plot(x, np.cos(x))
plt.legend(['sin(x)', 'cos(x)'],loc='upper right')
ax2 = fig.add_subplot(1,2,2)
random_arr = np.random.randn(100)
plt.plot(random_arr)
plt.title('標(biāo)準(zhǔn)正態(tài)分布')
```