Matplotlib自定義坐標(biāo)軸刻度的實(shí)現(xiàn)示例
雖然 Matplotlib 默認(rèn)的坐標(biāo)軸定位器(locator)
與格式生成器(formatter)
可以滿足大部分需求,但是并非對(duì)每一幅圖都合適。此次我將通過(guò)一些示例演示如何將坐標(biāo)軸刻度調(diào)整為你需要的位置與格式。
在介紹示例之前,我們最好先對(duì) Matplotlib 圖形的對(duì)象層級(jí)有更深入的理解。Matplotlib 的目標(biāo)是用 Python 對(duì)象表現(xiàn)任意圖形元素。例如,想想前面介紹的 figure 對(duì)象
,它其實(shí)就是一個(gè)盛放圖形元素的包圍盒(bounding box)
??梢詫⒚總€(gè) Matplotlib 對(duì)象都看成是子對(duì)象(sub-object)
的容器,例如每個(gè) figure 都會(huì)包含一個(gè)或多個(gè) axes 對(duì)象
,每個(gè) axes 對(duì)象又會(huì)包含其他表示圖形內(nèi)容的對(duì)象。
坐標(biāo)軸刻度線也不例外。每個(gè) axes 都有 xaxis 和 yaxis 屬性,每個(gè)屬性同樣包含構(gòu)成坐標(biāo)軸的線條、刻度和標(biāo)簽的全部屬性。
1 主要刻度與次要刻度
每一個(gè)坐標(biāo)軸都有主要
刻度線與次要
刻度線。顧名思義,主要刻度往往更大或更顯著,而次要刻度往往更小。雖然一般情況下 Matplotlib 不會(huì)使用次要刻度,但是你會(huì)在對(duì)數(shù)圖中看到它們
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np ax = plt.axes(xscale='log', yscale='log') plt.show()
我們發(fā)現(xiàn)每個(gè)主要刻度都顯示為一個(gè)較大的刻度線和標(biāo)簽,而次要刻度都顯示為一個(gè)較小的刻度線,且不顯示標(biāo)簽。
可以通過(guò)設(shè)置每個(gè)坐標(biāo)軸的 formatter 與 locator 對(duì)象,自定義這些刻度屬性(包括刻度線的位置和標(biāo)簽)。來(lái)檢查一下圖形 x 軸的屬性:
In[1]: print(ax.xaxis.get_major_locator()) print(ax.xaxis.get_minor_locator())
<matplotlib.ticker.LogLocator object at 0x107530cc0> <matplotlib.ticker.LogLocator object at 0x107530198>
In[2]: print(ax.xaxis.get_major_formatter()) print(ax.xaxis.get_minor_formatter())
<matplotlib.ticker.LogFormatterMathtext object at 0x107512780> <matplotlib.ticker.NullFormatter object at 0x10752dc18>
我們會(huì)發(fā)現(xiàn),主要刻度標(biāo)簽和次要刻度標(biāo)簽的位置都是通過(guò)一個(gè) LogLocator 對(duì)象
(在對(duì)數(shù)圖中可以看到)設(shè)置的。然而,次要刻度有一個(gè) NullFormatter 對(duì)象
處理標(biāo)簽,這樣標(biāo)簽就不會(huì)在圖上顯示了。
下面來(lái)演示一些示例,看看不同圖形的定位器與格式生成器是如何設(shè)置的。
2 隱藏刻度與標(biāo)簽
隱藏圖形的 x 軸標(biāo)簽與 y 軸刻度
最常用的刻度 / 標(biāo)簽格式化操作可能就是隱藏刻度與標(biāo)簽了,可以通過(guò) plt.NullLocator()
與 plt.NullFormatter()
實(shí)現(xiàn),如下所示
ax = plt.axes() ax.plot(np.random.rand(50)) ax.yaxis.set_major_locator(plt.NullLocator()) ax.xaxis.set_major_formatter(plt.NullFormatter())
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np ax = plt.axes() ax.plot(np.random.rand(50)) ax.yaxis.set_major_locator(plt.NullLocator()) ax.xaxis.set_major_formatter(plt.NullFormatter()) plt.show()
需要注意的是,我們移除了 x 軸的標(biāo)簽(但是保留了刻度線 / 網(wǎng)格線),以及 y 軸的刻度(標(biāo)簽也一并被移除)。
隱藏人臉圖形的坐標(biāo)軸
在許多場(chǎng)景中都不需要刻度線,比如當(dāng)你想要顯示一組圖形時(shí)。舉個(gè)例子,不同人臉的照片,就是經(jīng)常用于研究有監(jiān)督機(jī)器學(xué)習(xí)問(wèn)題的示例:
fig, ax = plt.subplots(5, 5, figsize=(5, 5)) fig.subplots_adjust(hspace=0, wspace=0) # 從scikit-learn獲取一些人臉照片數(shù)據(jù) from sklearn.datasets import fetch_olivetti_faces faces = fetch_olivetti_faces().images for i in range(5): for j in range(5): ax[i, j].xaxis.set_major_locator(plt.NullLocator()) ax[i, j].yaxis.set_major_locator(plt.NullLocator()) ax[i, j].imshow(faces[10 * i + j], cmap="bone")
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np fig, ax = plt.subplots(5, 5, figsize=(5, 5)) fig.subplots_adjust(hspace=0, wspace=0) # 從scikit-learn獲取一些人臉照片數(shù)據(jù) from sklearn.datasets import fetch_olivetti_faces faces = fetch_olivetti_faces().images for i in range(5): for j in range(5): ax[i, j].xaxis.set_major_locator(plt.NullLocator()) ax[i, j].yaxis.set_major_locator(plt.NullLocator()) ax[i, j].imshow(faces[10 * i + j], cmap="bone") plt.show()
需要注意的是,由于每幅人臉圖形默認(rèn)都有各自的坐標(biāo)軸,然而在這個(gè)特殊的可視化場(chǎng)景中,刻度值(本例中是像素值)的存在并不能傳達(dá)任何有用的信息,因此需要將定位器設(shè)置為空。
3 增減刻度數(shù)量
刻度擁擠的圖形
默認(rèn)刻度標(biāo)簽有一個(gè)問(wèn)題,就是顯示較小圖形時(shí),通??潭蕊@得十分擁擠。我們可以在下圖的網(wǎng)格中看到類似的問(wèn)題:
fig, ax = plt.subplots(4, 4, sharex=True, sharey=True)
自定義刻度數(shù)量
尤其是 x 軸,數(shù)字幾乎都重疊在一起,辨識(shí)起來(lái)非常困難。我們可以用 plt.MaxNLocator()
來(lái)解決這個(gè)問(wèn)題,通過(guò)它可以設(shè)置最多需要顯示多少刻度。根據(jù)設(shè)置的最多刻度數(shù)量,Matplotlib 會(huì)自動(dòng)為刻度安排恰當(dāng)?shù)奈恢茫?/p>
# 為每個(gè)坐標(biāo)軸設(shè)置主要刻度定位器 for axi in ax.flat: axi.xaxis.set_major_locator(plt.MaxNLocator(3)) axi.yaxis.set_major_locator(plt.MaxNLocator(3)) fig
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np fig, ax = plt.subplots(4, 4, sharex=True, sharey=True) # 為每個(gè)坐標(biāo)軸設(shè)置主要刻度定位器 for axi in ax.flat: axi.xaxis.set_major_locator(plt.MaxNLocator(3)) axi.yaxis.set_major_locator(plt.MaxNLocator(3)) fig plt.show()
這樣圖形就顯得更簡(jiǎn)潔了。如果你還想要獲得更多的配置功能,那么可以試試 plt.MultipleLocator
,我們將在接下來(lái)的內(nèi)容中介紹它。
4 花哨的刻度格式
默認(rèn)帶整數(shù)刻度的圖
Matplotlib 默認(rèn)的刻度格式可以滿足大部分的需求。雖然默認(rèn)配置已經(jīng)很不錯(cuò)了,但是有時(shí)候你可能需要更多的功能,例如下圖中的正弦曲線和余弦曲線:
# 畫正弦曲線和余弦曲線 fig, ax = plt.subplots() x = np.linspace(0, 3 * np.pi, 1000) ax.plot(x, np.sin(x), lw=3, label='Sine') ax.plot(x, np.cos(x), lw=3, label='Cosine') # 設(shè)置網(wǎng)格、圖例和坐標(biāo)軸上下限 ax.grid(True) ax.legend(frameon=False) ax.axis('equal') ax.set_xlim(0, 3 * np.pi);
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np # 畫正弦曲線和余弦曲線 fig, ax = plt.subplots() x = np.linspace(0, 3 * np.pi, 1000) ax.plot(x, np.sin(x), lw=3, label='Sine') ax.plot(x, np.cos(x), lw=3, label='Cosine') # 設(shè)置網(wǎng)格、圖例和坐標(biāo)軸上下限 ax.grid(True) ax.legend(frameon=False) ax.axis('equal') ax.set_xlim(0, 3 * np.pi); plt.show()
在 π / 2 的倍數(shù)上顯示刻度
我們可能想稍稍改變一下這幅圖。首先,如果將刻度與網(wǎng)格線畫在 π 的倍數(shù)上,圖形會(huì)更加自然。可以通過(guò)設(shè)置一個(gè) MultipleLocator
來(lái)實(shí)現(xiàn),它可以將刻度放在你提供的數(shù)值的倍數(shù)上。為了更好地測(cè)量,在 π /4
的倍數(shù)上添加主要刻度和次要刻度
ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4)) fig
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np # 畫正弦曲線和余弦曲線 fig, ax = plt.subplots() x = np.linspace(0, 3 * np.pi, 1000) ax.plot(x, np.sin(x), lw=3, label='Sine') ax.plot(x, np.cos(x), lw=3, label='Cosine') # 設(shè)置網(wǎng)格、圖例和坐標(biāo)軸上下限 ax.grid(True) ax.legend(frameon=False) ax.axis('equal') ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4)) fig plt.show()
然而,這些刻度標(biāo)簽看起來(lái)有點(diǎn)奇怪:雖然我們知道它們是 π 的倍數(shù),但是用小數(shù)表示圓周率不太直觀。因此,我們可以用刻度格式生成器來(lái)修改。
自定義刻度標(biāo)簽
由于沒有內(nèi)置的格式生成器可以直接解決問(wèn)題,因此需要用plt.FuncFormatter
來(lái)實(shí)現(xiàn),用一個(gè)自定義的函數(shù)設(shè)置不同刻度標(biāo)簽的顯示
def format_func(value, tick_number): # 找到 π /2的倍數(shù)刻度 N = int(np.round(2 * value / np.pi)) if N == 0: return "0" elif N == 1: return r"$\pi/2$" elif N == 2: return r"$\pi$" elif N % 2 > 0: return r"${0}\pi/2$".format(N) else: return r"${0}\pi$".format(N // 2) ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func)) fig
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') import numpy as np # 畫正弦曲線和余弦曲線 fig, ax = plt.subplots() x = np.linspace(0, 3 * np.pi, 1000) ax.plot(x, np.sin(x), lw=3, label='Sine') ax.plot(x, np.cos(x), lw=3, label='Cosine') # 設(shè)置網(wǎng)格、圖例和坐標(biāo)軸上下限 ax.grid(True) ax.legend(frameon=False) ax.axis('equal') def format_func(value, tick_number): # 找到 π /2的倍數(shù)刻度 N = int(np.round(2 * value / np.pi)) if N == 0: return "0" elif N == 1: return r"$\pi/2$" elif N == 2: return r"$\pi$" elif N % 2 > 0: return r"${0}\pi/2$".format(N) else: return r"${0}\pi$".format(N // 2) ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func)) fig plt.show()
這樣就好看多啦!其實(shí)我們已經(jīng)用了 Matplotlib 支持 LaTeX 的功能,在數(shù)學(xué)表達(dá)式兩側(cè)加上美元符號(hào)( $
),這樣可以非常方便地顯示數(shù)學(xué)符號(hào)和數(shù)學(xué)公式。在這個(gè)示例中, " $ \pi $
"就表示圓周率符合 π
。
當(dāng)你準(zhǔn)備展示或打印圖形時(shí), plt.FuncFormatter() 不僅可以為自定義圖形刻度提供十分靈活的功能,而且用法非常簡(jiǎn)單。
5 格式生成器與定位器小結(jié)
前面已經(jīng)介紹了一些格式生成器與定位器,下面用表格簡(jiǎn)單地總結(jié)一下內(nèi)置的格式生成器與定位器選項(xiàng)。關(guān)于兩者更詳細(xì)的信息,請(qǐng)參考各自的程序文檔或者 Matplotlib 的在線文檔。以下的所有類都在 plt 命名空間內(nèi)。
定位器類 | 描述 |
---|---|
NullLocator | 無(wú)刻度 |
FixedLocator | 刻度位置固定 |
IndexLocator | 用索引作為定位器(如 x = range(len(y))) |
LinearLocator | 從 min 到 max 均勻分布刻度 |
LogLocator | 從 min 到 max 按對(duì)數(shù)分布刻度 |
MultipleLocator | 刻度和范圍都是基數(shù)(base)的倍數(shù) |
MaxNLocator | 為最大刻度找到最優(yōu)位置 |
AutoLocator | (默認(rèn))以 MaxNLocator 進(jìn)行簡(jiǎn)單配置 |
AutoMinorLocator | 次要刻度的定位器 |
格式生成器類 | 描述 |
---|---|
NullFormatter | 刻度上無(wú)標(biāo)簽 |
IndexFormatter | 將一組標(biāo)簽設(shè)置為字符串 |
FixedFormatter | 手動(dòng)為刻度設(shè)置標(biāo)簽 |
FuncFormatter | 用自定義函數(shù)設(shè)置標(biāo)簽 |
FormatStrFormatter | 為每個(gè)刻度值設(shè)置字符串格式 |
ScalarFormatter | (默認(rèn))為標(biāo)量值設(shè)置標(biāo)簽 |
LogFormatter | 對(duì)數(shù)坐標(biāo)軸的默認(rèn)格式生成器 |
到此這篇關(guān)于Matplotlib自定義坐標(biāo)軸刻度的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Matplotlib自定義坐標(biāo)軸刻度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python利用matplotlib.pyplot繪圖時(shí)如何設(shè)置坐標(biāo)軸刻度
- Python設(shè)置matplotlib.plot的坐標(biāo)軸刻度間隔以及刻度范圍
- Python繪圖Matplotlib之坐標(biāo)軸及刻度總結(jié)
- matplotlib如何設(shè)置坐標(biāo)軸刻度的個(gè)數(shù)及標(biāo)簽的方法總結(jié)
- 如何利用Python和matplotlib更改縱橫坐標(biāo)刻度顏色
- matplotlib圖例、標(biāo)簽、坐標(biāo)軸刻度的字體設(shè)置方式
- Python3使用matplotlib繪圖時(shí),坐標(biāo)軸刻度不從X軸、y軸兩端開始
- Matplotlib自定義坐標(biāo)刻度的使用示例
相關(guān)文章
夯實(shí)基礎(chǔ)python集合的應(yīng)用場(chǎng)景及字符串定義和表示
這篇文章主要為大家介紹了python集合的應(yīng)用場(chǎng)景及字符串定義和表示,來(lái)幫大家夯實(shí)基礎(chǔ),有需要的朋友可以借鑒參考下,希望能夠有所幫助2023-10-10python GUI庫(kù)圖形界面開發(fā)之PyQt5動(dòng)態(tài)加載QSS樣式文件
這篇文章主要介紹了python GUI庫(kù)圖形界面開發(fā)之PyQt5動(dòng)態(tài)加載QSS樣式表,需要的朋友可以參考下2020-02-02Python數(shù)據(jù)可視化:頂級(jí)繪圖庫(kù)plotly詳解
今天小編就為大家分享一篇Python數(shù)據(jù)可視化:頂級(jí)繪圖庫(kù)plotly詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12python基于win32api實(shí)現(xiàn)鍵盤輸入
這篇文章主要介紹了python基于win32api實(shí)現(xiàn)鍵盤輸入,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-12-12Python中NumPy的線性代數(shù)子模塊linalg詳解
這篇文章主要介紹了Python中NumPy的線性代數(shù)子模塊linalg詳解,NumPy 的線性代數(shù)子模塊linalg提供了 20 余個(gè)函數(shù),用于求解行列式、逆矩陣、特征值、特征向量,以及矩陣分解等,需要的朋友可以參考下2023-08-08Python中Playwright?與?pyunit?結(jié)合使用詳解
這篇文章主要介紹了Python中Playwright?與?pyunit?結(jié)合使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03