數據可視化
基本概念
數據可視化是指藉助於圖形化的手段,清晰、快捷有效的傳達與溝通信息。同時,也可以輔助用戶做出相應的判斷,更好的去洞悉數據背後的價值。
字不如表,表不如圖。
觀察號碼的頻率,每個號碼出現了多少次?
文字
08 10 15 20 30 31 33 06
01 09 10 17 21 28 32 13
02 05 08 13 19 21 28 10
03 05 07 14 18 23 25 07
…… ……
表格
圖形
通過可視化圖表方式,就可以清晰的表達信息。
可視化圖形輔助決策
1854 年英國倫敦霍亂病流行時,斯諾博士在繪有霍亂流行地區所有道路、房屋、飲用水機井等內容的城區地圖上,標出了每個霍亂病死者的住家位置,得到了霍亂病死者居住位置分佈圖,發現了霍亂病源之所在:布勞德大街(現布勞維克大街)的公用抽水機。
matplotlib
matplotlib是用於Python的繪圖庫,提供各種常用圖形的繪製。例如,條形圖,柱形圖,線圖,散點圖等。
安裝
pip install matplotlib
導入
根據慣例,使用如下的方式導入:
import matplotlib as mpl`
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.pyplot as plt
圖形繪製
繪製線圖
可以通過matplotlib.pyplot的plot方法進行圖形繪製。
- plot(y)
- plot(y, ‘格式’)
- plot(x, y)
- plot(x, y, ‘格式’)
- plot(x1, y1, ‘格式1’, x2, y2, ‘格式2’ …… xn, yn, 格式n)
# 如果沒有指定橫座標x,則橫座標x會從0開始,自增。(0,1,2,3,4……)
# 如果我們只繪製一個值,該值就是一個點,我們需要指定marker來設置標記,否則該點不可見。
# plt.plot(10, marker="o")
# 繪製多個點。
# plt.plot([1, 5, 8, 4, 6], marker=">")
# 顯式指定橫座標。
# plt.plot([1, 3, 5, 7, 9], [2, 4, 16, 8, 10], marker="o")
# plt.plot([2, 13, 25, 7, 9], [3, 14, 6, 28, 9], marker="o")
# 可以一次性繪製多個圖形。
# 格式字符串可以指定標記形狀,顏色與線型。
plt.plot([1, 3], [2, 4], "r-o", [5, 8], [10, 2], "g--x")
在這裏插入圖片描述
圖形交互式設置
我們可以設置jupyter notebook圖形是否交互式顯示,默認爲否。
- %matplotlib notebook
- %matplotlib inline
%matplotlib notebook
%matplotlib inline
plt.plot([1, 2, 3], [5, 8, 11])
設置中文支持
matplotlib默認情況下不支持中文顯示,如果需要顯示中文,則我們需要做一些額外的設置操作。設置可以分爲:
- 全局設置
- 局部設置
全局設置
我們可以通過執行:
mpl.rcParams["font.family"] = "中文字體名稱"
mpl.rcParams["axes.unicode_minus"]=False
進行設置。常用的設置如下:
- font.family 字體的名稱
- sans-serif 西文字體(默認)
- SimHei 中文黑體
- FangSong 中文仿宋
- YouYuan 中文幼圓
- STSong 華文宋體
- Kaiti 中文楷體
- LiSu 中文隸書
- font.style 字體的風格
- normal 常規(默認)
- italic 斜體
- oblique 傾斜
- font.size 字體的大小(默認10)
- axes.unicode_minus 是否使用Unicode的減號(負號)【在支持中文顯示狀態下,需要設置爲False】
局部設置
在需要顯式的文字中,使用fontproperties參數進行設置。
說明:
- 如果全局設置與局部設置衝突,以局部設置爲準。
# 默認情況下,matplotlib使用的是西方字體(不支持中文的),
# 如果需要顯式中文,可以將字體設置成支持中文的字體。
mpl.rcParams["font.family"] = "Kaiti"
# mpl.rcParams["font.family"] = "sans-serif"
plt.plot([1, -2, 3], [5, -10, 6])
plt.title("中文標題")
# plt.title("abcde")
# 當字體設置成支持中文的字體時,負號也會也會使用Unicode字符集的負號(不支持顯式)。
# 我們需要恢復成ASCII字符集中的負號。
mpl.rcParams["axes.unicode_minus"]=False
# 設置字體形狀.(對中文的字體支持的不太好)
mpl.rcParams["font.style"] = "italic"
# 設置字體的大小。
# mpl.rcParams["font.size"] = 10
局部設置。
plt.plot([1, 2, 3], [4, 5, 8])
plt.title(“標題信息”, fontsize=20, fontproperties=“LiSu”)
保存圖表
通過plt的savefig方法將當前的圖形保存到硬盤或者類文件對象中。
- dpi:每英寸分辨率點數。
- facecolor:設置圖像的背景色。
- bbox_inches:設置爲tight,可以緊湊保存圖像。
x = np.linspace(0, 2 * np.pi, num=100)
y = np.sin(x)
plt.plot(x, y)
# plt.savefig("c:/1.png", dpi=50, facecolor="g", bbox_inches="tight")
# savefig除了可以將圖片保存在硬盤上之外,也可以將圖片保存到類文件對象中。
# from io import StringIO
# 二進制(字節)格式的類文件對象。
from io import BytesIO
b = BytesIO()
# 保存到類文件對象中。
plt.savefig(b, dpi=50)
display(b.tell())
b.seek(0)
# b.read(50)
# b.getvalue()
讀取圖像
from PIL import Image
image = Image.open(“c:/1.png”)
image.show()
對Image來說,open可以傳遞文件的路徑,也可以傳遞一個類文件對象。
image = Image.open(b)
image.show()
顏色,點標記與線型設置
我們可以在繪製圖形時,顯式指定圖形的顏色,點標記或線條形狀。具體設置可以查看幫助文檔。
- color©:線條顏色。
- linestyle(ls):線條形狀。
- linewidth(lw):線寬。
- marker:點標記形狀。
- markersize(ms):點標記的大小。
- markeredgecolor(mec):點邊緣顏色。
- markeredgewidth(mew):點邊緣寬度。
- markerfacecolor(mfc):點的顏色。
說明:
- 顏色,點標記與線型可以使用一個參數進行設置。
- 顏色除了可以使用預設簡寫的字符之外,也可以使用全稱(例如red)也可以使用RGB顏色表示。
plt.plot([1, 2, 3], [4, 5, 6], “r–o”)
plt.plot([1, 2, 3], [4, 5, 6], c=“y”, ls="-.", lw=1, marker=“o”, ms=10, mec=“g”, mew=3, mfc=“r”)
透明度設置
在繪製圖像時,我們可以通過alpha參數來控制圖像的透明度,值在0 ~ 1之間。0爲完全透明,1爲不透明。
# 可以使用alpha參數指定圖像的透明度。0完全透明,1不透明(默認)
plt.plot(5, "o", alpha=0.)
圖例設置
在繪製多條線時,可以設置圖例來標註每條線所代表的含義,使圖形更加清晰易懂。
可以採用如下的方式設置圖例:
- 調用plt的legend函數,傳遞一個標籤數組,指定每次plot圖形的標籤。
- 在繪製的時候通過label參數指定圖例中顯示的名稱,然後調用legend函數生成圖例。
legend常用的參數:
- loc:指定圖例的位置。默認爲best。也可以指定座標(元組),基於圖像左下角計算。
- frameon:設置是否含有邊框。
- title:設置圖例的標題。
- ncol:圖例顯示的列數,默認爲1。
last_year = np.random.randint(400, 500, 12)
this_year = np.random.randint(400, 500, 12)
# plt.plot(range(1, 13), last_year, marker="o")
# plt.plot(range(1, 13), this_year, marker="o")
# 設置圖例 1 在legend方法中,按順序指定每次繪圖的標籤。
# plt.legend(["2017", "2018"])
# 2 在繪製(plot)圖形時,指定label參數值,該參數值爲圖例需要顯示的文本。
plt.plot(range(1, 13), last_year, marker="o", label="2017")
plt.plot(range(1, 13), this_year, marker="o", label="2018")
# 設置圖例時,可以通過loc屬性來設置圖例顯示的位置。如果沒有顯式指定,則參數值爲右上角。
# loc屬性可以指定爲字符串,整數值。或者是一個元組(兩個float值指定比例)此時,會根據圖像比例計算
# 圖例顯示的位置。原點在左下角。
# plt.legend(loc=(0, 0))
# frameon參數用來設置圖例是否顯示邊框。默認爲True。
# plt.legend(loc="best", frameon=False)
# 設置圖例顯示的標題。
# plt.legend(loc="best", title="圖例標題")
# ncol參數用來設置圖例顯示的列數。(默認爲1。)
# plt.legend(loc="best", ncol=2)
網格設置
可以通過plt的grid方法來設置是否顯示網格。True爲顯示,False不顯示。ax.grid(color=‘r’, linestyle=’-’, linewidth=2)
- color:設置網格線顏色
- axis:設置網格線顯示x,y或者全部顯示(x,y,both)。
- linestyle:設置網格線形狀。
- linewidth:設置網格線寬度。
plt.plot([1, 2, 3, 4], [8, 2, 9, 6])
# 顯示網格,默認不顯示網格。
plt.grid(True, color="g", axis="both", linestyle="-.", linewidth=5)
繪圖區域設置
我們可以在一張圖上繪製多個圖形,當然,我們也可以將不同的圖形繪製到多個不同的區域當中。
我們可以採用以下方式來實現多個區域的繪製(創建子繪圖區域):
- 通過Figure對象調用add_subplot方法。
- 通過plt的subplot方法。
- 通過plt的subplots方法。
子區域1:add_subplot方法
- 首先創建matplotlib.figure.Figure對象,然後通過Figure對象的add_subplot方法增加子繪圖區域。
- add_subplot方法中,需要指定子區域的行數、列數與當前要繪製的子區域。
- add_subplot方法會返回子繪圖對象(軸對象),通過該對象即可實現繪圖(matplotlib.axes._subplots.AxesSubplot)。
在繪製圖形時,總是需要創建Figure對象。如果沒有顯式創建,則plt會隱式創建一個Figure對象。在繪製圖形時,既可以使用plt來繪製,也可以使用子繪圖對象來繪製。
如果使用plt對象繪製,則總是在最後創建的繪圖區域上進行繪製,如果此時尚未創建繪圖區域,則會自動創建。
說明:
- add_subplot方法的參數,即可以使用三個參數分開傳遞,也可以使用一個參數整體傳遞。
- 可以通過plt.subplots_adjust方法來調整子繪圖的位置與子繪圖之間的距離。(left, right, top, bottom, wspace, hspace)
- 創建子區域時,可以使用facecolor設置繪圖區域的背景色。
# 創建Figure對象,然後通過調用add_subplot增加繪圖區域。
# 創建Figure對象。(畫圖必備的底層對象)
f = plt.figure()
# 調用add_subplot增加子繪圖區域對象,返回AxesSubplot類型的對象。
# 三個參數,行數,列數,當前的繪圖區域
ax = f.add_subplot(1, 2, 1)
# 調用AxesSubplot對象的plot方法,進行圖形繪製。
# ax.plot([1, 5, 8], [10, -3, 6])
plt.plot([1, 5, 8], [10, -3, 6])
# ax = f.add_subplot(1, 2, 2)
ax = f.add_subplot("122", facecolor="g")
# ax.plot([10, 15, 28], [1, -33, 26])
plt.plot([10, 15, 28], [1, -33, 26])
# 我們可以使用plt或者是AxesSubplot對象,調用plot方法進行繪製。
# 當我們使用plt繪製時,永遠會在最後一次創建的子繪圖區域上進行繪製。
# 如果當前沒有子繪圖區域,此時會創建一個。
# 調整距離(繪圖區域之間的距離以及繪圖區域與邊界間的距離)
plt.subplots_adjust(wspace=0.5)
子區域2:subplot方法
通過調用plt的subplot方法創建子繪圖區域,該方法返回子繪圖對象。此種方式下,會隱式創建Figure對象。
實際上,這種創建子繪圖區域的方式,底層也是通過第一種方式實現的。
# ax = plt.subplot(1, 2, 1)
plt.subplot(1, 2, 1)
plt.plot([1, 2, 3], [5, 8, 6])
plt.subplot(1, 2, 2)
plt.plot([10, 5, 8], [1, 2, 3])
子區域3:subplots方法
通過plt的subplots方法創建子繪圖區域,該方法返回一個元組(Figure對象與所有子繪圖對象,如果是多個子繪圖對象,則返回一個ndarray數組)。可以通過sharex與sharey來指定是否共享x軸與y軸。
# subplots會返回一個元組。(Figure對象, 所有子繪圖區域對象(數組))
# 可以使用sharex與sharey設置是否共享x(y)軸。
figure, ax = plt.subplots(1, 2, sharey=True)
ax[0].plot([10, 20, 30], "r-o")
ax[1].plot([1, 2, 3], "g-o")
繪圖區域大小設置
如果繪圖子區域較多,可能會有些擁擠。此時,我們可以調整繪圖區域的大小。方式如下:
- 在調用
plt.figure()
創建Figure對象時,通過figsize參數指定。單位爲英寸。 - 在創建Figure對象後,可以通過Figure對象的set_size_inches方法設置。
說明:
- 如果沒有顯式創建Figure對象,可以通過plt的gcf函數獲取當前的Figure對象。
# 創建Figure對象,通過figsize參數指定畫布的大小。(單位:英寸)
# plt.figure(figsize=(10, 10))
# 第二種方式。創建Figure對象後,調用set_size_inches方法設置畫布大小。
f = plt.figure()
# f.set_size_inches(10, 10)
# 獲取當前的Figure對象。
# f = plt.gcf()
# f.set_size_inches(10, 10)
f2 = plt.gcf()
# 如果顯式創建Figure對象,則獲取的Figure對象就是我們創建的對象。
display(f is f2)
plt.plot([1, 2, 3], [20, 10, -5])
標籤與刻度設置
可以通過plt對象的相關方法來設置(或獲取)標籤與刻度等信息。設置還是獲取,取決於是否傳遞實際參數。
- plt.xlim 設置或獲取x軸刻度範圍。
- plt.ylim 設置或獲取y軸刻度範圍。
- plt.xticks 設置或獲取x軸顯示的刻度與標籤。
- plt.yticks 設置或獲取y軸顯示的刻度與標籤。
- plt.axis 可以同時設置或獲取x與y軸的刻度範圍,或者是取消刻度顯示。
- 無參數:返回一個元組。(xmin, xmax, ymin, ymax)
- (xmin, xmax, ymin, ymax) 同時設置x與y軸的刻度範圍。
- off 取消座標軸顯示。
- tight:座標軸緊湊顯示。
- equal:x與y具有同樣的長度。
軸標籤說明與標題設置
- plt.xlabel 設置x軸的標籤說明。
- plt.ylabel 設置y軸的標籤說明。
- plt.title 設置標題。
# 關於這些方法的使用,需要注意:既可以進行設置,也可以獲取相關的值。
# 設置還是獲取,取決於方法的參數。當方法沒有參數時,獲取值。當方法具有參數時,設置值。
plt.plot([1,2,3],[10,20,30])
# 設置或獲取x(y)軸的界限。
# display(plt.xlim())
# plt.xlim([0, 20])
# plt.ylim()
# plt.ylim([0, 5])
# 設置(獲取)軸顯示的刻度。
# plt.xticks([1, 3, 5, 7, 9])
# plt.xticks()
# xticks可以傳遞兩個數據,第1個數組用來設置顯示的刻度,第2個數據用來設置刻度顯示的標籤。
# 如果沒有顯式指定第2個數組,刻度的顯示標籤就等於刻度的值。
# plt.xticks([1, 5, 9], ["前期", "中期", "後期"], rotation=90)
# 可以獲取或設置x與y軸的界限值。(4個值)
# plt.axis()
# plt.axis([0, 20, -1, 5])
# 不顯示座標軸。
# plt.axis("off")
# 座標軸緊湊顯示
# plt.axis("tight")
# 讓座標軸x與y的比例尺相同。
# plt.axis("equal")
# 設置x軸顯示的內容。
plt.xlabel("x軸")
# 設置y軸顯示的內容。
plt.ylabel("y軸")
# 設置標題。
plt.title("標題")
通過繪圖對象設置
除了通過plt對象外,我們還可以通過子繪圖對象來設置與獲取標籤與刻度。
- ax.set_xlim 設置x軸刻度範圍。
- ax.get_xlim 獲取x軸刻度範圍。
- ax.set_xticks 設置x軸顯示的刻度。
- ax.get_xticks 獲取x軸顯示的刻度。
- ax.set_xticklabels 設置x軸顯示的刻度標籤。默認顯示的是就是刻度值。
- ax.get_xticklabels 獲取x軸顯示的刻度標籤。
也可以設置標籤說明與標題。
- ax.set_xlabel 設置x軸的標籤說明。
- ax.get_xlabel 獲取x軸的標籤說明。
- ax.set_title 設置標題。
- ax.get_title 獲取標題。
說明:
- 如果需要設置或者獲取y軸,只需要將x換成y即可。
- 在設置標籤時,可以使用rotation參數,令標籤旋轉。
ax = plt.subplot(1, 1, 1)
ax.set_xlim(10, 20)
ax.set_xticks([10, 15, 20])
ax.set_xticklabels(["早", "中", "晚"])
ax.set_xlabel("x軸")
ax.set_ylabel("y軸")
ax.set_title("標題")
添加註解
我們可以在圖形上繪製文本等說明信息(註解)。
普通文本
plt.text 顯示文本(基於座標)
plt.figtext 顯示文本(基於圖片)
箭頭
plt.arrow 根據起點座標(x,y)與各自軸的長度(x + dx, y + dy)繪製箭頭。
- width 箭頭尾部的寬度。
- head_width 箭頭的寬度。
- head_length 箭頭的長度。
箭頭與文本
plt.annotate 顯示箭頭與文本。
- xy 箭頭指向座標
- xytext 文本起點座標。(箭頭尾部座標)
- arrowprops 字典類型,可設置箭頭的屬性。
- facecolor 箭頭的顏色
- headwidth 箭頭的寬度
- width 箭尾的寬度
- shrink 收縮大小
- headlength 箭頭的長度
- arrowstyle 一些預設的箭頭樣式。當含有該參數時,上述4項參數將不再有效。
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
# 基於座標顯示文本
# plt.text(5, 0.5, "這是正弦曲線")
# 基於圖像的比例,顯示文本。
# plt.figtext(0.2, 0.5, "這是正弦曲線")
# 繪製箭頭。x,y起始點座標。 x + dx, y + dy 終止點座標。
# plt.arrow(5, 0.5, -2, -0.1, width=0.05, head_width=0.1, head_length=0.1, color="g")
# 同時繪製箭頭與文本
# plt.annotate("這是正弦曲線", xy=(3, 0.25), xytext=(5, 0.5), arrowprops={"facecolor":"g", "headwidth":15, "width": 7, "shrink":0.1})
# plt.annotate("這是正弦曲線", xy=(3, 0.25), xytext=(5, 0.5), arrowprops={"arrowstyle": "<->"})
plt.annotate("這是正弦曲線", xy=(3, 0.25), xytext=(5, 0.5), arrowprops=dict(facecolor="g", headwidth=15, width=7, shrink=0.5))
繪圖樣式設置
我們可以通過plt.style.use("樣式名")
來設置繪圖使用的樣式。
說明:
執行plt.style.available
來獲取所有的繪圖樣式。
顯示所有支持的樣式
plt.style.available
設置參數指定的樣式。
plt.style.use(“ggplot”)
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.annotate("這是正弦曲線", xy=(3, 0.25), xytext=(5, 0.5), arrowprops=dict(facecolor="g", headwidth=15, width=7, shrink=0.5))
圖形類型
折線圖
plt.plot
# 折線圖適合顯示具有趨勢的增加變化的數據。例如,股市走勢,降雨量,氣溫變量。
plt.plot(np.random.randint(1, 10, 20))
柱形圖 / 條形圖
plt.bar 柱形圖
plt.barh 條形圖
# 柱形圖,條形圖適合比較數值的大小。
# plt.bar(range(1, 11), np.random.randint(100, 200, 10))
plt.barh(range(1, 11), np.random.randint(100, 200, 10))
餅圖
plt.pie 餅圖
- labels 每個部分顯示的標籤。
- explode 指定每個部分距離圓心的偏移量(單位爲半徑的長度)。
- colors 指定每個部分的顏色。
- autopct 設置每個部分顯示的比例值(格式化)。
- couterclock 是否逆時針繪圖。默認爲True。
- startangle 初始繪圖點位置(逆時針偏移x軸的角度)。默認爲偏移0度(x軸)。
- shadow 是否含有陰影,默認爲False。
# 餅圖適合於表示比例大小。(數量不宜過多,否則會顯得凌亂)
# plt.pie([10, 20, 30, 40], labels=["A部門", "B部門", "C部門", "D部門"], explode=[0, 0, 0, 0.5], colors=["r", "g", "b", "y"])
# plt.pie([10, 20, 30, 40], labels=["A部門", "B部門", "C部門", "D部門"], autopct="%.2f", counterclock=False)
plt.pie([10, 20, 30, 40], labels=["A部門", "B部門", "C部門", "D部門"], startangle=90, shadow=True)
散點圖 / 氣泡圖
散點圖適合於用來顯示與比較數據的分佈狀態。
- marker 點的標記。
- s 點的大小。
- color 點的顏色。
說明:
- color與s參數可以統一設置,也可以爲每一個點單獨設置。
# 散點圖/氣泡圖適合表示數據整體的分佈信息。
# 散點圖可以表示兩個維度,加上氣泡大小,顏色,可以多表示兩個維度。
# plt.scatter(np.random.randint(0, 100, 100), np.random.randint(0, 100, 100), s=150, color="g")
# s(點的大小)與color(點的顏色)既可以統一制定,也可以單獨制定。
# plt.scatter([1, 2, 3, 4], [4, 3, 2, 1], s=[10, 20, 30, 40], color=["r", "g", "b", "y"])
size = [10, 20, 30, 40]
color = ["r", "g", "b", "y"]
plt.scatter(np.random.randint(0, 100, 100), np.random.randint(0, 100, 100),
s=np.random.choice(size, 100), color=np.random.choice(color, 100))
直方圖
直方圖(histogram)可以看成是一種特殊的柱形圖,用來將連續的數據頻率(數量)進行離散化顯示。在直方圖中,數據被分割成若干區間,然後統計每個區間數據出現的頻率(數量)。
我們可以通過plt.hist來繪製直方圖。
- bins:設置分割區間的數量。
- normed:進行歸一化顯示。(概率密度)
# 直方圖適合將連續值轉換成離散值,方便分組統計數量。
plt.hist(np.random.randn(100), bins=10, normed=True)
# 返回的兩個ndarray。
# 第一個ndarray表示每個桶中元素的數量。
# 第二個naarray表示每個桶的界限。(前閉後開,最後一個桶例外,兩端都是閉區間。)
箱線圖
箱線圖也稱盒須圖。通過極值與Q1,Q2,Q3值來描述數據。通過箱線圖,我們可以發現數據中的離羣(異常)值。
箱線圖的離羣點定義爲:Q3+1.5IQR和Q1-1.5IQR。其中IQR爲兩個四分位之間的距離。
# 箱線圖適合分析離羣值(異常值)。
x = np.random.normal(0, 10, size=1000)
plt.boxplot(x)
Series與DataFrame圖形繪製
Series與DataFrame類型的對象也支持圖形繪製,使用對象的plot方法即可。
如果我們需要繪製圖形的數據就存在Series或者DataFrame對象中,我們就可以直接繪製,而無需使用plt.plot。
其他類型圖形
plot默認繪製的是線形圖,我們可以通過調整其kind參數的值來繪製其他類型的圖形。
- line:線形圖
- bar:柱形圖
- barh:條形圖
- hist:直方圖
- kde / density:核密度圖
- pie:餅圖
- box:箱線圖
- area:面積圖
參數:
- color
- alpha
- stacked:是否堆疊。
說明:
plot(kind=“類型”)也可以通過plot."類型"來進行繪製。
import pandas as pd
df = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]])
display(df)
# df.plot(marker="o")
# stacked設置爲True,堆疊圖。
# df.plot(kind="bar", stacked=True)
# df[2].plot()
# df.plot(kind="pie", y=3)
df.plot(kind="pie", subplots=True)
希望對你有所幫助!