【Python进阶】带你使用Matplotlib进行可视化
歡迎來(lái)到專(zhuān)欄《Python進(jìn)階》。在這個(gè)專(zhuān)欄中,我們會(huì)講述Python的各種進(jìn)階操作,包括Python對(duì)文件、數(shù)據(jù)的處理,Python各種好用的庫(kù)如NumPy、Scipy、Matplotlib、Pandas的使用等等。我們的初心就是帶大家更好的掌握Python這門(mén)語(yǔ)言,讓它能為我所用。
今天是《Python進(jìn)階》專(zhuān)欄的第五期,在本期中,我們將主要介紹如何使用Matplotlib這個(gè)第三方庫(kù)進(jìn)行數(shù)據(jù)可視化。
作者&編輯 | 湯興旺
“美麗的可視化可反映出所描述數(shù)據(jù)的品質(zhì),顯式地揭示出源數(shù)據(jù)中內(nèi)在和隱式的屬性和關(guān)系,讀者了解了這些屬性和關(guān)系之后,可以因此而獲取新的知識(shí)、洞察力和樂(lè)趣?!?/p>
以上是書(shū)籍《數(shù)據(jù)可視化之美》對(duì)可視化的解讀。說(shuō)的很有道理,相信大家聽(tīng)說(shuō)過(guò)“一圖勝千言”這句話,當(dāng)看到一堆數(shù)據(jù)時(shí),若你對(duì)數(shù)字不夠敏感,肯定會(huì)費(fèi)勁半天找不到規(guī)律,但若用一張圖來(lái)表達(dá)時(shí),相信你一定會(huì)一目了然。下面我就大家使用Matplotlib對(duì)數(shù)據(jù)進(jìn)行美麗的可視化。
1?Matplotlib 的基本操作
在Matplotlib中有三個(gè)基本概念,分別是Figure、axes和axis。
下面我來(lái)詳細(xì)解釋下這三個(gè)基本概念。在Matplotlib中,figure你可以理解成一個(gè)畫(huà)布或者一個(gè)窗口,axes是指畫(huà)布上的一個(gè)區(qū)域,你畫(huà)的圖就在這個(gè)區(qū)域上。你可以把figure看成一張白紙,在紙上的任何區(qū)域畫(huà)圖,確定畫(huà)圖區(qū)域并確定作圖的一些方式的東西的就是axes,即坐標(biāo)對(duì)象(坐標(biāo)系)。
由于在一張白紙上可以有幾個(gè)區(qū)域進(jìn)行畫(huà)圖,另外畫(huà)圖區(qū)域必須存在于白紙上才有意義。因此在figure上可有多個(gè)axes,axes必在figure上,要畫(huà)圖必有axes。
另外axis就是我們平時(shí)常見(jiàn)的坐標(biāo)軸,如x軸、y軸等。
對(duì)于上面的概念我們可以用下圖進(jìn)行直觀理解。
通過(guò)上面的講解,我們知道在Matplotlib中的圖像都位于figure畫(huà)布中,因此可以使用plt.figure創(chuàng)建一個(gè)新畫(huà)布。如果要在一個(gè)圖表中繪制多個(gè)子圖,可使用subplot。
話不多說(shuō),我們直接看下面代碼:
import matplotlib.pyplot as plt
ax4 = fig.add_subplot(2, 2, 4)
首先,創(chuàng)建了一個(gè)figure,然后在這個(gè)figure上畫(huà)了四個(gè)區(qū)域,即四個(gè)子圖,分別是直方圖、三點(diǎn)圖、折線圖,還有一個(gè)是只有坐標(biāo)軸的圖。
如果我想要畫(huà)多個(gè)figure應(yīng)該怎么辦呢?實(shí)際上如果要同時(shí)繪制多個(gè)圖表,可以給figure()傳遞一個(gè)整數(shù)參數(shù)指定figure對(duì)象的序號(hào)。如下例所示:
import matplotlib.pyplot as plt
import numpy as np
plt.figure(1)? # 創(chuàng)建圖表1
plt.figure(2)? # 創(chuàng)建圖表2
ax1 = plt.subplot(211)? # 在圖表2中創(chuàng)建子圖1
ax2 = plt.subplot(212)? # 在圖表2中創(chuàng)建子圖2
x = np.linspace(0, 3, 100)
for i in range(5):
? ? plt.figure(1)? # 選擇圖表1
? ? plt.plot(x, np.exp(i * x / 3))
? ? plt.sca(ax1)? # 選擇圖表2的子圖1
? ? plt.plot(x, np.sin(i * x))
? ? plt.sca(ax2)? # 選擇圖表2的子圖2
? ? plt.plot(x, np.cos(i * x))
plt.show()
執(zhí)行完上面代碼后,如下圖。
2 Matplotlib的進(jìn)階操作
在1中的兩個(gè)示例中,我們會(huì)發(fā)現(xiàn)手動(dòng)創(chuàng)建figure,都使用了plt.figure()。如果沒(méi)有plt.figure()可以嗎?請(qǐng)看下面的示例:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-np.pi, 5*np.pi, num = 100)
y = np.sin(x)
plt.plot(x,y)
plt.show()
我們會(huì)發(fā)現(xiàn)這段代碼中,沒(méi)有plt.figure()也畫(huà)出了圖,WHY?難道前面誤導(dǎo)了大家?我在前面說(shuō)過(guò),若沒(méi)有figure就沒(méi)有axes!
當(dāng)然這個(gè)鍋我不背,實(shí)際上這里plt.plot()是通過(guò)plt.gca()獲得當(dāng)前axes對(duì)象的ax,如果沒(méi)有會(huì)自動(dòng)創(chuàng)建一個(gè),可以理解為就是figure。然后再調(diào)用ax.plot方法實(shí)現(xiàn)真正的繪圖。
Matplotlib實(shí)際上是一套面向?qū)ο蟮睦L圖庫(kù),它所繪制的圖表中每個(gè)圖表元素,如線條 Line2D、文字Text、刻度等在內(nèi)存中都有一個(gè)對(duì)象與之對(duì)應(yīng)。為將面向?qū)ο蟮睦L圖庫(kù)包裝成只使用函數(shù)的調(diào)用接口,pyplot模塊內(nèi)部保存了當(dāng)前圖表以及當(dāng)前子圖等信息。當(dāng)前的圖表和子圖可以使用plt.gcf()和plt.gca()獲得,分別表示"Get Current Figure"和"Get Current Axes"。在pyplot模塊中,許多函數(shù)都是對(duì)當(dāng)前的figure或axes對(duì)象進(jìn)行處理,比如說(shuō):
plt.plot()實(shí)際上會(huì)通過(guò)plt.gca()獲得當(dāng)前的axes對(duì)象ax,然后再調(diào)用ax.plot()方法實(shí)現(xiàn)真正繪圖。
2.1 對(duì)圖進(jìn)行裝扮
上面3個(gè)示例中均沒(méi)有展示圖例、標(biāo)注等,下面我們通過(guò)下面的示例來(lái)分享如何對(duì)一個(gè)圖進(jìn)行裝扮。
import matplotlib.pyplot as plt
import numpy as np
fig, ax1 = plt.subplots(figsize=(8, 4))
r = np.linspace(0, 10, 100)
a = 4 * np.pi * r ** 2? # area
v = (4 * np.pi / 3) * r ** 3? # volume
ax1.set_title("surface area and volume of a sphere", fontsize=16)
ax1.set_xlabel("radius [m]", fontsize=16)
ax1.plot(r, a, lw=2, color="blue")
ax1.set_ylabel(r"surface area ($m^2$)", fontsize=16, color="blue")
for label in ax1.get_yticklabels():
? ? label.set_color("blue")
ax2 = ax1.twinx()
ax2.plot(r, v, lw=2, color="red")
ax2.set_ylabel(r"volume ($m^3$)", fontsize=16, color="red")
for label in ax2.get_yticklabels():
? ? label.set_color("red")
fig.tight_layout()
plt.show()
在上面的示例中我們通過(guò)set.title()設(shè)置了圖的標(biāo)題,通過(guò)set_xlabel和set_ylabel設(shè)置了y軸的標(biāo)簽,另外也通過(guò)get_yticklabels()和get_xticklabels()設(shè)置了坐標(biāo)軸上刻度的不同的屬性。
2.2、對(duì)圖的某個(gè)細(xì)節(jié)進(jìn)行放大
平時(shí)我們?cè)谔幚韴D的時(shí)候,有時(shí)候需要對(duì)圖的局部細(xì)節(jié)進(jìn)行查看,這時(shí)候就需要對(duì)細(xì)節(jié)進(jìn)行放大,對(duì)于這個(gè)問(wèn)題該怎么解決呢?請(qǐng)看下面的案例:
import matplotlib.pyplot as plt
如果我想要對(duì)上圖的橫縱標(biāo)在4附近的局部峰值進(jìn)行放大查看,即下圖圈紅部分進(jìn)行放大查看,應(yīng)該如何操作呢?
代碼如下:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
fig = plt.figure(figsize=(8, 4))
def f(x):
? ? return 1 / (1 + x ** 2) + 0.1 / (1 + ((3 - x) / 0.1) ** 2)
def plot_and_format_axes(ax, x, f, fontsize):
? ? ax.plot(x, f(x), linewidth=2)
? ? ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(5))
? ? ax.yaxis.set_major_locator(mpl.ticker.MaxNLocator(4))
? ? ax.set_xlabel(r"$x$", fontsize=fontsize)
? ? ax.set_ylabel(r"$f(x)$", fontsize=fontsize)
ax = fig.add_axes([0.1, 0.15, 0.8, 0.8], facecolor="#f5f5f5")
x = np.linspace(-4, 14, 1000)
plot_and_format_axes(ax, x, f, 18)
x0, x1 = 2.5, 3.5
ax = fig.add_axes([0.5, 0.5, 0.38, 0.42], facecolor='none')
x = np.linspace(x0, x1, 1000)
plot_and_format_axes(ax, x, f, 14)
plt.show()
代碼區(qū)紅色部分即實(shí)現(xiàn)放大部分的代碼。實(shí)際是添加了另外一個(gè)axes,只不過(guò)這個(gè)axes包含在主圖的axes中。
總結(jié)
本期我們介紹了Matplotlib中的一些應(yīng)用,希望您能借助這個(gè)工具畫(huà)出精美的圖表。
下期預(yù)告:Python庫(kù)Pandas的高級(jí)應(yīng)用
知識(shí)星球推薦
有三AI編程與開(kāi)源框架知識(shí)星球由我親自維護(hù),內(nèi)設(shè)caffe實(shí)戰(zhàn),Python實(shí)戰(zhàn),Python每日一練,Pytorch實(shí)戰(zhàn)、C++每一一練等板塊。近期我重點(diǎn)更新caffe的實(shí)戰(zhàn)教程,包括模型定義、數(shù)據(jù)處理、源碼解讀、定制自己的caffe等等,歡迎大家了解加入,我們一起攻破編程與開(kāi)源框架。
轉(zhuǎn)載文章請(qǐng)后臺(tái)聯(lián)系
侵權(quán)必究
往期精選
【Python進(jìn)階】Python進(jìn)階專(zhuān)欄、編程與開(kāi)源框架知識(shí)星球上線,等你來(lái)follow
【Python進(jìn)階】實(shí)戰(zhàn)Python圖像文件操作基本編程
【雜談】菜鳥(niǎo)誤入linux會(huì)有哪些慘痛的經(jīng)歷
【Python進(jìn)階】你的真的明白NumPy中的ndarray嗎?
【Python進(jìn)階】Python中的異常處理
【TensorFlow2.0】以后我們?cè)僖搽x不開(kāi)Keras了?
【TensorFlow2.0】數(shù)據(jù)讀取與使用方式
【TensorFlow2.0】如何搭建網(wǎng)絡(luò)模型
總結(jié)
以上是生活随笔為你收集整理的【Python进阶】带你使用Matplotlib进行可视化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【NLP】如何系统性的学习NLP,有三A
- 下一篇: 【杂谈】手把手带你配置深度学习环境