數(shù)據(jù)科學 IPython 筆記本 8.13 自定義刻度

8.13 自定義刻度

原文:Customizing Ticks

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

本節(jié)是《Python 數(shù)據(jù)科學手冊》(Python Data Science Handbook)的摘錄妨退。

Matplotlib 的默認刻度定位器和格式化程序拦坠,在許多常見情況下通常都足夠了,但對于每個繪圖都不是最佳選擇隔心。本節(jié)將提供幾個刻度位置和格式的示例坎缭,它們調(diào)整你感興趣的特定繪圖類型竟痰。

在我們進入示例之前,我們最好進一步了解 Matplotlib 繪圖的對象層次結(jié)構(gòu)掏呼。Matplotlib 旨在用 Python 對象表示繪圖中出現(xiàn)的所有內(nèi)容:例如坏快,回想一下figure是繪圖元素所在的邊框。每個 Matplotlib 對象也可以充當子對象的容器:例如憎夷,每個figure可以包含一個或多個axes對象莽鸿,它們的每個又包含表示繪圖內(nèi)容的其他對象。

刻度線也不例外拾给。 每個axes都有屬性xaxisyaxis祥得,它們又具有一些屬性,包括構(gòu)成軸域的直線蒋得,刻度和標簽级及。

主要和次要刻度

在每個軸內(nèi),有主要刻度標記和次要刻度標記的概念额衙。 正如名稱所暗示的那樣饮焦,主要刻度通常更大或更明顯怕吴,而次要刻度通常更小。 默認情況下县踢,Matplotlib 很少使用次要刻度转绷,但是你可以在對數(shù)繪圖中看到它們:

import matplotlib.pyplot as plt
plt.style.use('classic')
%matplotlib inline
import numpy as np

ax = plt.axes(xscale='log', yscale='log')
ax.grid();
png

我們在這里看到每個主刻度線顯示為一個大刻度線和一個標簽,而每個次刻度線顯示為一個沒有標簽的較小刻度線硼啤。

這些刻度屬性 - 位置和標簽 - 也就是說议经,可以通過設置每個軸的formatterlocator對象來定制。 讓我們檢查剛剛展示的繪圖的x軸:

print(ax.xaxis.get_major_locator())
print(ax.xaxis.get_minor_locator())

'''
<matplotlib.ticker.LogLocator object at 0x10dbaf630>
<matplotlib.ticker.LogLocator object at 0x10dba6e80>
'''

print(ax.xaxis.get_major_formatter())
print(ax.xaxis.get_minor_formatter())

'''
<matplotlib.ticker.LogFormatterMathtext object at 0x10db8dbe0>
<matplotlib.ticker.NullFormatter object at 0x10db9af60>
'''

我們看到主要和次要刻度標簽的位置都由LogLocator指定(這對于對數(shù)圖是有意義的)丙曙。 但是爸业,次要刻度的標簽格式為NullFormatter:這表示不會顯示任何標簽。我們現(xiàn)在將展示一些為各種圖設置這些定位器和格式化器的示例亏镰。

隱藏刻度或標簽

也許最常見的刻度/標簽格式化操作是隱藏刻度或標簽。這可以使用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())
png

請注意索抓,我們已經(jīng)從x軸移除了標簽(但保留了刻度線/網(wǎng)格線),并從y軸中刪除了刻度線(以及標簽)毯炮。
在許多情況下逼肯,不顯示刻度可能很有用 - 例如,當你想要顯示圖像網(wǎng)格的時候桃煎。
例如篮幢,考慮下圖,它包含不同的面部圖像为迈,這是監(jiān)督機器學習問題中常用的一個例子(例如三椿,參見“深入:支持向量機”):

fig, ax = plt.subplots(5, 5, figsize=(5, 5))
fig.subplots_adjust(hspace=0, wspace=0)

# 從 sklearn 獲取一些人臉數(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")
png

請注意,每個圖像都有自己的軸域葫辐,我們將定位器設置為null搜锰,因為刻度值(在這種情況下為像素數(shù))不會傳達這個特定可視化的相關(guān)信息。

減少或增加刻度數(shù)量

默認設置的一個常見問題是耿战,較小的子圖最終會擁有密集的標簽蛋叼。我們可以在這里顯示的繪圖網(wǎng)格中看到它:

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

特別是對于x刻度,數(shù)字幾乎重疊并使它們很難看清剂陡。我們可以用plt.MaxNLocator()解決這個問題狈涮,它允許我們指定要顯示的最大刻度數(shù)。給定此最大數(shù)量鸭栖,Matplotlib 將使用內(nèi)部邏輯來選擇特定的刻度位置:

# 對于每個軸歌馍,設置 x 和 y 主要定位器
for axi in ax.flat:
    axi.xaxis.set_major_locator(plt.MaxNLocator(3))
    axi.yaxis.set_major_locator(plt.MaxNLocator(3))
fig
png

這使事情變得更加干凈。 如果你想要更多地控制等間隔的刻度位置纤泵,你也可以使用plt.MultipleLocator骆姐,我們將在下一節(jié)討論镜粤。

花式刻度格式

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')

# 配置網(wǎng)格,圖例和限制
ax.grid(True)
ax.legend(frameon=False)
ax.axis('equal')
ax.set_xlim(0, 3 * np.pi);
png

我們可能想做一些改變带射。 首先同规,以 π 的倍數(shù)的刻度線和網(wǎng)格線來區(qū)分這些數(shù)據(jù)更加自然。 我們可以通過設置MultipleLocator來實現(xiàn)窟社,它可以在你提供的數(shù)字的倍數(shù)處券勺,設置刻度線。 為了更好地衡量灿里,我們將以π/4的倍數(shù)添加主要和次要刻度:

ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2))
ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4))
fig
png

但現(xiàn)在這些刻度標簽看起來有點傻:我們可以看到它們是 π 的倍數(shù)关炼,但十進制表示并沒有立即傳達這一點。要解決這個問題匣吊,我們可以更改刻度格式化器儒拂。對于我們想要做的事情,沒有內(nèi)置格式化器色鸳,所以我們改為使用plt.FuncFormatter社痛,它接受用戶定義的函數(shù),對刻度輸出進行細粒度控制:

def format_func(value, tick_number):
    # 尋找 pi/2 倍數(shù)的數(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
png

這要好得多命雀! 請注意蒜哀,我們已經(jīng)使用了 Matplotlib 的 LaTeX 支持,通過將字符串括在美元符號中來指定吏砂。 這對于顯示數(shù)學符號和公式非常方便:在這種情況下撵儿,$\pi$顯示為希臘字符π

plt.FuncFormatter()提供繪圖刻度外觀的極細粒度控制赊抖,并且在準備繪圖用于演示或發(fā)布時非常方便统倒。

格式化器和定位器的總結(jié)

我們已經(jīng)提到了一些可用的格式化器和定位器。我們將簡要列出所有內(nèi)置定位器和格式化器的選項來結(jié)束本節(jié)氛雪。 對于其中任何內(nèi)容的更多信息房匆,請參閱文檔字符串或 Matplotlib 在線文檔。plt命名空間中提供以下東西:

定位器類 描述
NullLocator 沒有刻度
FixedLocator 刻度定位器是固定的
IndexLocator 索引繪圖的定位器(也就是报亩,其中x = range(len(y))
LinearLocator 等間隔的刻度浴鸿,從最小值到最大值
LogLocator 對數(shù)刻度,從最小值到最大值
MultipleLocator 刻度和范圍是基數(shù)的倍數(shù)
MaxNLocator 在不錯的位置尋找小于等于最大值的刻度數(shù)
AutoLocator (默認)帶有簡單默認值的MaxNLocator
AutoMinorLocator 用于次要刻度的定位器
格式化器類 描述
NullFormatter 刻度上沒有標簽
IndexFormatter 從一列標簽中設置字符串
FixedFormatter 手動為標簽設置字符串
FuncFormatter 使用用戶定義的函數(shù)設置標簽
FormatStrFormatter 對每個值使用格式化字符串
ScalarFormatter (默認)用于標量值的格式化器
LogFormatter 對數(shù)軸域的默認格式化器

我們將在本書的其余部分看到更多這些例子弦追。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岳链,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子劲件,更是在濱河造成了極大的恐慌掸哑,老刑警劉巖约急,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異苗分,居然都是意外死亡旁瘫,警方通過查閱死者的電腦和手機锌钮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門旷档,熙熙樓的掌柜王于貴愁眉苦臉地迎上來襟交,“玉大人,你說我怎么就攤上這事择浊〈鞑罚” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵琢岩,是天一觀的道長投剥。 經(jīng)常有香客問我,道長粘捎,這世上最難降的妖魔是什么薇缅? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮攒磨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汤徽。我一直安慰自己娩缰,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布谒府。 她就那樣靜靜地躺著拼坎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪完疫。 梳的紋絲不亂的頭發(fā)上泰鸡,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音壳鹤,去河邊找鬼盛龄。 笑死,一個胖子當著我的面吹牛芳誓,可吹牛的內(nèi)容都是我干的余舶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼锹淌,長吁一口氣:“原來是場噩夢啊……” “哼匿值!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起赂摆,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤挟憔,失蹤者是張志新(化名)和其女友劉穎钟些,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绊谭,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡政恍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了龙誊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抚垃。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖趟大,靈堂內(nèi)的尸體忽然破棺而出鹤树,到底是詐尸還是另有隱情,我是刑警寧澤逊朽,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布罕伯,位于F島的核電站,受9級特大地震影響叽讳,放射性物質(zhì)發(fā)生泄漏追他。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一岛蚤、第九天 我趴在偏房一處隱蔽的房頂上張望邑狸。 院中可真熱鬧,春花似錦涤妒、人聲如沸单雾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽硅堆。三九已至,卻和暖如春贿讹,著一層夾襖步出監(jiān)牢的瞬間渐逃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工民褂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茄菊,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓助赞,卻偏偏與公主長得像买羞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子雹食,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容