欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Matplotlib自定義坐標軸刻度的實現示例

 更新時間:2020年06月18日 11:26:00   作者:ywsydwsbn  
這篇文章主要介紹了Matplotlib自定義坐標軸刻度的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

雖然 Matplotlib 默認的坐標軸定位器(locator)格式生成器(formatter)可以滿足大部分需求,但是并非對每一幅圖都合適。此次我將通過一些示例演示如何將坐標軸刻度調整為你需要的位置與格式。

在介紹示例之前,我們最好先對 Matplotlib 圖形的對象層級有更深入的理解。Matplotlib 的目標是用 Python 對象表現任意圖形元素。例如,想想前面介紹的 figure 對象,它其實就是一個盛放圖形元素的包圍盒(bounding box)??梢詫⒚總€ Matplotlib 對象都看成是子對象(sub-object)的容器,例如每個 figure 都會包含一個或多個 axes 對象,每個 axes 對象又會包含其他表示圖形內容的對象。

坐標軸刻度線也不例外。每個 axes 都有 xaxis 和 yaxis 屬性,每個屬性同樣包含構成坐標軸的線條、刻度和標簽的全部屬性。

1 主要刻度與次要刻度

每一個坐標軸都有主要刻度線與次要刻度線。顧名思義,主要刻度往往更大或更顯著,而次要刻度往往更小。雖然一般情況下 Matplotlib 不會使用次要刻度,但是你會在對數圖中看到它們

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as np
ax = plt.axes(xscale='log', yscale='log')
plt.show()


我們發(fā)現每個主要刻度都顯示為一個較大的刻度線和標簽,而次要刻度都顯示為一個較小的刻度線,且不顯示標簽。
可以通過設置每個坐標軸的 formatter 與 locator 對象,自定義這些刻度屬性(包括刻度線的位置和標簽)。來檢查一下圖形 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>

我們會發(fā)現,主要刻度標簽和次要刻度標簽的位置都是通過一個 LogLocator 對象(在對數圖中可以看到)設置的。然而,次要刻度有一個 NullFormatter 對象處理標簽,這樣標簽就不會在圖上顯示了。

下面來演示一些示例,看看不同圖形的定位器與格式生成器是如何設置的。

2 隱藏刻度與標簽

隱藏圖形的 x 軸標簽與 y 軸刻度

最常用的刻度 / 標簽格式化操作可能就是隱藏刻度與標簽了,可以通過 plt.NullLocator()plt.NullFormatter() 實現,如下所示

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 軸的標簽(但是保留了刻度線 / 網格線),以及 y 軸的刻度(標簽也一并被移除)。

隱藏人臉圖形的坐標軸

在許多場景中都不需要刻度線,比如當你想要顯示一組圖形時。舉個例子,不同人臉的照片,就是經常用于研究有監(jiān)督機器學習問題的示例:

fig, ax = plt.subplots(5, 5, figsize=(5, 5))
fig.subplots_adjust(hspace=0, wspace=0)
# 從scikit-learn獲取一些人臉照片數據
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獲取一些人臉照片數據
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()


需要注意的是,由于每幅人臉圖形默認都有各自的坐標軸,然而在這個特殊的可視化場景中,刻度值(本例中是像素值)的存在并不能傳達任何有用的信息,因此需要將定位器設置為空。

3 增減刻度數量

刻度擁擠的圖形

默認刻度標簽有一個問題,就是顯示較小圖形時,通??潭蕊@得十分擁擠。我們可以在下圖的網格中看到類似的問題:

fig, ax = plt.subplots(4, 4, sharex=True, sharey=True)

自定義刻度數量

尤其是 x 軸,數字幾乎都重疊在一起,辨識起來非常困難。我們可以用 plt.MaxNLocator()來解決這個問題,通過它可以設置最多需要顯示多少刻度。根據設置的最多刻度數量,Matplotlib 會自動為刻度安排恰當的位置:

# 為每個坐標軸設置主要刻度定位器
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)
# 為每個坐標軸設置主要刻度定位器
for axi in ax.flat:
  axi.xaxis.set_major_locator(plt.MaxNLocator(3))
  axi.yaxis.set_major_locator(plt.MaxNLocator(3))
fig
plt.show()


這樣圖形就顯得更簡潔了。如果你還想要獲得更多的配置功能,那么可以試試 plt.MultipleLocator ,我們將在接下來的內容中介紹它。

4 花哨的刻度格式

默認帶整數刻度的圖

Matplotlib 默認的刻度格式可以滿足大部分的需求。雖然默認配置已經很不錯了,但是有時候你可能需要更多的功能,例如下圖中的正弦曲線和余弦曲線:

# 畫正弦曲線和余弦曲線
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')
# 設置網格、圖例和坐標軸上下限
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')
# 設置網格、圖例和坐標軸上下限
ax.grid(True)
ax.legend(frameon=False)
ax.axis('equal')
ax.set_xlim(0, 3 * np.pi);
plt.show()

在 π / 2 的倍數上顯示刻度

我們可能想稍稍改變一下這幅圖。首先,如果將刻度與網格線畫在 π 的倍數上,圖形會更加自然??梢酝ㄟ^設置一個 MultipleLocator 來實現,它可以將刻度放在你提供的數值的倍數上。為了更好地測量,在 π /4 的倍數上添加主要刻度和次要刻度

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')
# 設置網格、圖例和坐標軸上下限
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()


然而,這些刻度標簽看起來有點奇怪:雖然我們知道它們是 π 的倍數,但是用小數表示圓周率不太直觀。因此,我們可以用刻度格式生成器來修改。

自定義刻度標簽

由于沒有內置的格式生成器可以直接解決問題,因此需要用plt.FuncFormatter 來實現,用一個自定義的函數設置不同刻度標簽的顯示

def format_func(value, tick_number):
  # 找到 π /2的倍數刻度
  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')
# 設置網格、圖例和坐標軸上下限
ax.grid(True)
ax.legend(frameon=False)
ax.axis('equal')
def format_func(value, tick_number):
  # 找到 π /2的倍數刻度
  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()


這樣就好看多啦!其實我們已經用了 Matplotlib 支持 LaTeX 的功能,在數學表達式兩側加上美元符號( $ ),這樣可以非常方便地顯示數學符號和數學公式。在這個示例中, " $ \pi $"就表示圓周率符合 π
當你準備展示或打印圖形時, plt.FuncFormatter() 不僅可以為自定義圖形刻度提供十分靈活的功能,而且用法非常簡單。

5 格式生成器與定位器小結

前面已經介紹了一些格式生成器與定位器,下面用表格簡單地總結一下內置的格式生成器與定位器選項。關于兩者更詳細的信息,請參考各自的程序文檔或者 Matplotlib 的在線文檔。以下的所有類都在 plt 命名空間內。

定位器類 描述
NullLocator 無刻度
FixedLocator 刻度位置固定
IndexLocator 用索引作為定位器(如 x = range(len(y)))
LinearLocator 從 min 到 max 均勻分布刻度
LogLocator 從 min 到 max 按對數分布刻度
MultipleLocator 刻度和范圍都是基數(base)的倍數
MaxNLocator 為最大刻度找到最優(yōu)位置
AutoLocator (默認)以 MaxNLocator 進行簡單配置
AutoMinorLocator 次要刻度的定位器

格式生成器類 描述
NullFormatter 刻度上無標簽
IndexFormatter 將一組標簽設置為字符串
FixedFormatter 手動為刻度設置標簽
FuncFormatter 用自定義函數設置標簽
FormatStrFormatter 為每個刻度值設置字符串格式
ScalarFormatter (默認)為標量值設置標簽
LogFormatter 對數坐標軸的默認格式生成器

到此這篇關于Matplotlib自定義坐標軸刻度的實現示例的文章就介紹到這了,更多相關Matplotlib自定義坐標軸刻度內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論