matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab類似的命令API,十分適合交互式地進行製圖。並且也能夠方便地將它做爲繪圖控件,嵌入GUI應用程序中。html
它的文檔至關完備,而且 Gallery頁面 中有上百幅縮略圖,打開以後都有源程序。所以若是你須要繪製某種類型的圖,只須要在這個頁面中瀏覽/複製/粘貼一下,基本上都能搞定。python
本章節做爲matplotlib的入門介紹,將較爲深刻地挖掘幾個例子,從中理解和學習matplotlib繪圖的一些基本概念。canvas
matplotlib的pyplot子庫提供了和matlab相似的繪圖API,方便用戶快速繪製2D圖表。讓咱們先來看一個簡單的例子:數組
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)
plt.figure(figsize=(8,4))
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
plt.show()
圖5.1 調用pyplot庫快速將數據繪製成曲線圖app
matplotlib中的快速繪圖的函數庫能夠經過以下語句載入:dom
import matplotlib.pyplot as plt
pylab模塊編輯器
matplotlib還提供了名爲pylab的模塊,其中包括了許多numpy和pyplot中經常使用的函數,方便用戶快速進行計算和繪圖,能夠用於IPython中的快速交互式使用。函數
接下來調用figure建立一個繪圖對象,而且使它成爲當前的繪圖對象。工具
plt.figure(figsize=(8,4))
也能夠不建立繪圖對象直接調用接下來的plot函數直接繪圖,matplotlib會爲咱們自動建立一個繪圖對象。若是須要同時繪製多幅圖表的話, 能夠是給figure傳遞一個整數參數指定圖標的序號,若是所指定序號的繪圖對象已經存在的話,將不建立新的對象,而只是讓它成爲當前繪圖對象。佈局
經過figsize參數能夠指定繪圖對象的寬度和高度,單位爲英寸;dpi參數指定繪圖對象的分辨率,即每英寸多少個像素,缺省值爲80。所以本例中所建立的圖表窗口的寬度爲8*80 = 640像素。
可是用工具欄中的保存按鈕保存下來的png圖像的大小是800*400像素。這是由於保存圖表用的函數savefig使用不一樣的DPI配 置,savefig函數也有一個dpi參數,若是不設置的話,將使用matplotlib配置文件中的配置,此配置能夠經過以下語句進行查看,關於配置文 件將在後面的章節進行介紹:
>>> import matplotlib
>>> matplotlib.rcParams["savefig.dpi"]
100
下面的兩行程序經過調用plot函數在當前的繪圖對象中進行繪圖:
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2)
plt.plot(x,z,"b--",label="$cos(x^2)$")
plot函數的調用方式很靈活,第一句將x,y數組傳遞給plot以後,用關鍵字參數指定各類屬性:
第二句直接經過第三個參數"b--"指定曲線的顏色和線型,這個參數稱爲格式化參數,它可以經過一些易記的符號快速指定曲線的樣式。其中b表示藍色,"--"表示線型爲虛線。在IPython中輸入 "plt.plot?" 能夠查看格式化字符串的詳細配置。
接下來經過一系列函數設置繪圖對象的各個屬性:
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
最後調用plt.show()顯示出咱們建立的全部繪圖對象。
matplotlib所繪製的圖的每一個組成部分都對應有一個對象,咱們能夠經過調用這些對象的屬性設置方法set_*或者pyplot的屬性設置函 數setp設置其屬性值。例如plot函數返回一個 matplotlib.lines.Line2D 對象的列表,下面的例子顯示如何設置Line2D對象的屬性:
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> x = np.arange(0, 5, 0.1)
>>> line, = plt.plot(x, x*x) # plot返回一個列表,經過line,獲取其第一個元素
>>> # 調用Line2D對象的set_*方法設置屬性值
>>> line.set_antialiased(False)
>>> # 同時繪製sin和cos兩條曲線,lines是一個有兩個Line2D對象的列表
>>> lines = plt.plot(x, np.sin(x), x, np.cos(x)) #
>>> # 調用setp函數同時配置多個Line2D對象的多個屬性值
>>> plt.setp(lines, color="r", linewidth=2.0)
這段例子中,經過調用Line2D對象line的set_antialiased方法,關閉對象的反鋸齒效果。或者經過調用plt.setp函數配置多個Line2D對象的顏色和線寬屬性。
一樣咱們能夠經過調用Line2D對象的get_*方法,或者plt.getp函數獲取對象的屬性值:
>>> line.get_linewidth()
1.0
>>> plt.getp(lines[0], "color") # 返回color屬性
'r'
>>> plt.getp(lines[1]) # 輸出所有屬性
alpha = 1.0
animated = False
antialiased or aa = True
axes = Axes(0.125,0.1;0.775x0.8)
... ...
注意getp函數只能對一個對象進行操做,它有兩種用法:
matplotlib的整個圖表爲一個Figure對象,此對象在調用plt.figure函數時返回,咱們也能夠經過plt.gcf函數獲取當前的繪圖對象:
>>> f = plt.gcf()
>>> plt.getp(f)
alpha = 1.0
animated = False
...
Figure對象有一個axes屬性,其值爲AxesSubplot對象的列表,每一個AxesSubplot對象表明圖表中的一個子圖,前面所繪製的圖表只包含一個子圖,當前子圖也能夠經過plt.gca得到:
>>> plt.getp(f, "axes")
[<matplotlib.axes.AxesSubplot object at 0x05CDD170>]
>>> plt.gca()
<matplotlib.axes.AxesSubplot object at 0x05CDD170>
用plt.getp能夠發現AxesSubplot對象有不少屬性,例如它的lines屬性爲此子圖所包括的 Line2D 對象列表:
>>> alllines = plt.getp(plt.gca(), "lines")
>>> alllines
<a list of 3 Line2D objects>
>>> alllines[0] == line # 其中的第一條曲線就是最開始繪製的那條曲線
True
經過這種方法咱們能夠很容易地查看對象的屬性和它們之間的包含關係,找到須要配置的屬性。
一個繪圖對象(figure)能夠包含多個軸(axis),在Matplotlib中用軸表示一個繪圖區域,能夠將其理解爲子圖。上面的第一個例子 中,繪圖對象只包括一個軸,所以只顯示了一個軸(子圖)。咱們可使用subplot函數快速繪製有多個軸的圖表。subplot函數的調用形式以下:
subplot(numRows, numCols, plotNum)
subplot將整個繪圖區域等分爲numRows行 * numCols列個子區域,而後按照從左到右,從上到下的順序對每一個子區域進行編號,左上的子區域的編號爲1。若是numRows,numCols和 plotNum這三個數都小於10的話,能夠把它們縮寫爲一個整數,例如subplot(323)和subplot(3,2,3)是相同的。 subplot在plotNum指定的區域中建立一個軸對象(就是前邊創建的索引)。若是新建立的軸和以前建立的軸重疊的話,以前的軸將被刪除。
下面的程序建立3行2列共6個軸,經過axisbg參數給每一個軸設置不一樣的背景顏色。
for idx, color in enumerate("rgbyck"):
plt.subplot(320+idx+1, axisbg=color)
plt.show()
圖5.2 用subplot函數將Figure分爲六個子圖區域
若是但願某個軸佔據整個行或者列的話,能夠以下調用subplot:
plt.subplot(221) # 第一行的左圖
plt.subplot(222) # 第一行的右圖
plt.subplot(212) # 第二整行
plt.show()
圖5.3 將Figure分爲三個子圖區域
當繪圖對象中有多個軸的時候,能夠經過工具欄中的Configure Subplots按鈕,交互式地調節軸之間的間距和軸與邊框之間的距離。若是但願在程序中調節的話,能夠調用subplots_adjust函數,它有 left, right, bottom, top, wspace, hspace等幾個關鍵字參數,這些參數的值都是0到1之間的小數,它們是以繪圖區域的寬高爲1進行正規化以後的座標或者長度。
一幅圖有許多須要配置的屬性,例如顏色、字體、線型等等。咱們在繪圖時,並無一一對這些屬性進行配置,許多都直接採用了Matplotlib的缺省配置。Matplotlib將缺省配置保存在一個文件中,經過更改這個文件,咱們能夠修改這些屬性的缺省值。
Matplotlib 使用配置文件 matplotlibrc 時的搜索順序以下:
經過下面的語句能夠獲取用戶配置路徑:
>>> import matplotlib
>>> matplotlib.get_configdir()
'C:\\Documents and Settings\\zhang\\.matplotlib'
經過下面的語句能夠得到目前使用的配置文件的路徑:
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
'C:\\Python26\\lib\\site-packages\\matplotlib\\mpl-data\\matplotlibrc'
因爲在當前路徑和用戶配置路徑中都沒有找到位置文件,所以最後使用的是系統配置路徑下的配置文件。若是你將matplotlibrc複製一份到腳本的當前目錄下:
>>> import os
>>> os.getcwd()
'C:\\zhang\\doc'
複製配置文件以後再運行:
>>> matplotlib.matplotlib_fname()
'C:\\zhang\\doc\\matplotlibrc'
若是你用文本編輯器打開此配置文件的話,你會發現它其實是定義了一個字典。爲了對衆多的配置進行區分,關鍵字能夠用點分開。
配置文件的讀入可使用 rc_params 函數,它返回一個配置字典:
>>> matplotlib.rc_params()
{'agg.path.chunksize': 0,
'axes.axisbelow': False,
'axes.edgecolor': 'k',
'axes.facecolor': 'w',
... ...
在matplotlib模塊載入的時候會調用rc_params,並把獲得的配置字典保存到rcParams變量中:
>>> matplotlib.rcParams
{'agg.path.chunksize': 0,
'axes.axisbelow': False,
... ...
matplotlib將使用rcParams中的配置進行繪圖。用戶能夠直接修改此字典中的配置,所作的改變會反映到此後所繪製的圖中。例以下面的腳本所繪製的線將帶有圓形的點標識符:
>>> matplotlib.rcParams["lines.marker"] = "o"
>>> import pylab
>>> pylab.plot([1,2,3])
>>> pylab.show()
爲了方便配置,可使用rc函數,下面的例子同時配置點標識符、線寬和顏色:
>>> matplotlib.rc("lines", marker="x", linewidth=2, color="red")
若是但願恢復到缺省的配置(matplotlib載入時從配置文件讀入的配置)的話,能夠調用 rcdefaults 函數。
>>> matplotlib.rcdefaults()
若是手工修改了配置文件,但願從新從配置文件載入最新的配置的話,能夠調用:
>>> matplotlib.rcParams.update( matplotlib.rc_params() )
matplotlib API包含有三層:
FigureCanvas和Renderer須要處理底層的繪圖操做,例如使用wxPython在界面上繪圖,或者使用PostScript繪製 PDF。Artist則處理全部的高層結構,例如處理圖表、文字和曲線等的繪製和佈局。一般咱們只和Artist打交道,而不須要關心底層的繪製細節。
Artists分爲簡單類型和容器類型兩種。簡單類型的Artists爲標準的繪圖元件,例如Line2D、 Rectangle、 Text、AxesImage 等等。而容器類型則能夠包含許多簡單類型的Artists,使它們組織成一個總體,例如Axis、 Axes、Figure等。
:簡單類型就是些,基本的2d線,矩形,文本,軸圖 容器類型,則是一個總體 liru axis 單軸圖,多軸圖,figure等。
直接使用Artists建立圖表的標準流程以下:
下面首先調用pyplot.figure輔助函數建立Figure對象,而後調用Figure對象的add_axes方法在其中建立一個Axes對 象,add_axes的參數是一個形如[left, bottom, width, height]的列表,這些數值分別指定所建立的Axes對象相對於fig的位置和大小,取值範圍都在0到1之間:
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> ax = fig.add_axes([0.15, 0.1, 0.7, 0.3]) 添加一個軸,
而後咱們調用ax的plot方法繪圖,建立一條曲線,而且返回此曲線對象(Line2D)。
>>> line, = ax.plot([1,2,3],[1,2,1]) 在軸上繪圖
>>> ax.lines
[<matplotlib.lines.Line2D object at 0x0637A3D0>]
>>> line
<matplotlib.lines.Line2D object at 0x0637A3D0>
ax.lines是一個爲包含ax的全部曲線的列表,後續的ax.plot調用會往此列表中添加新的曲線。若是想刪除某條曲線的話,直接今後列表中刪除便可。
Axes對象還包括許多其它的Artists對象,例如咱們能夠經過調用set_xlabel設置其X軸上的標題:
>>> ax.set_xlabel("time")
若是咱們查看set_xlabel的源代碼的話,會發現它是經過調用下面的語句實現的:
self.xaxis.set_label_text(xlabel)
若是咱們一直跟蹤下去,會發現Axes的xaxis屬性是一個XAxis對象:
>>> ax.xaxis
<matplotlib.axis.XAxis object at 0x06343230>
XAxis的label屬性是一個Text對象:
>>> ax.xaxis.label
<matplotlib.text.Text object at 0x06343290>
而Text對象的_text屬性爲咱們設置的值:
>>> ax.xaxis.label._text
'time'
這些對象都是Artists,所以也能夠調用它們的屬性獲取函數來得到相應的屬性:
>>> ax.xaxis.label.get_text()
'time'
圖表中的每一個元素都用一個matplotlib的Artist對象表示,而每一個Artist對象都有一大堆屬性控制其顯示效果。例如Figure對 象和Axes對象都有patch屬性做爲其背景,它的值是一個Rectangle對象。經過設置此它的一些屬性能夠修改Figrue圖表的背景顏色或者透 明度等屬性,下面的例子將圖表的背景顏色設置爲綠色:
>>> fig = plt.figure()
>>> fig.show()
>>> fig.patch.set_color("g")
>>> fig.canvas.draw()
patch的color屬性經過set_color函數進行設置,屬性修改以後並不會當即反映到圖表的顯示上,還須要調用fig.canvas.draw()函數纔可以更新顯示。
下面是Artist對象都具備的一些屬性:
Artist對象的全部屬性都經過相應的 get_* 和 set_* 函數進行讀寫,例以下面的語句將alpha屬性設置爲當前值的一半:
>>> fig.set_alpha(0.5*fig.get_alpha())
若是你想用一條語句設置多個屬性的話,可使用set函數:
>>> fig.set(alpha=0.5, zorder=2)
使用前面介紹的 matplotlib.pyplot.getp 函數能夠方便地輸出Artist對象的全部屬性名和值。
>>> plt.getp(fig.patch)
aa = True
alpha = 1.0
animated = False
antialiased or aa = True
... ...
如今咱們知道如何觀察和修改已知的某個Artist對象的屬性,接下來要解決如何找到指定的Artist對象。前面咱們介紹過Artist對象有容器類型和簡單類型兩種,這一節讓咱們來詳細看看容器類型的內容。
最大的Artist容器是matplotlib.figure.Figure,它包括組成圖表的全部元素。圖表的背景是一個Rectangle對 象,用Figure.patch屬性表示。當你經過調用add_subplot或者add_axes方法往圖表中添加軸(子圖時),這些子圖都將添加到 Figure.axes屬性中,同時這兩個方法也返回添加進axes屬性的對象,注意返回值的類型有所不一樣,實際上AxesSubplot是Axes的子 類。
>>> fig = plt.figure()
>>> ax1 = fig.add_subplot(211)
>>> ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
>>> ax1
<matplotlib.axes.AxesSubplot object at 0x056BCA90>
>>> ax2
<matplotlib.axes.Axes object at 0x056BC910>
>>> fig.axes
[<matplotlib.axes.AxesSubplot object at 0x056BCA90>,
<matplotlib.axes.Axes object at 0x056BC910>]
爲了支持pylab中的gca()等函數,Figure對象內部保存有當前軸的信息,所以不建議直接對Figure.axes屬性進行列表操做,而 應該使用add_subplot, add_axes, delaxes等方法進行添加和刪除操做。可是使用for循環對axes中的每一個元素進行操做是沒有問題的,下面的語句打開全部子圖的柵格。
>>> for ax in fig.axes: ax.grid(True)
Figure對象能夠擁有本身的文字、線條以及圖像等簡單類型的Artist。缺省的座標系統爲像素點,可是能夠經過設置Artist對象的 transform屬性修改座標系的轉換方式。最經常使用的Figure對象的座標系是以左下角爲座標原點(0,0),右上角爲座標(1,1)。下面的程序創 建並添加兩條直線到fig中:
>>> from matplotlib.lines import Line2D
>>> fig = plt.figure()
>>> line1 = Line2D([0,1],[0,1], transform=fig.transFigure, figure=fig, color="r")
>>> line2 = Line2D([0,1],[1,0], transform=fig.transFigure, figure=fig, color="g")
>>> fig.lines.extend([line1, line2])
>>> fig.show()
圖5.4 在Figure對象中手工繪製直線
注意爲了讓所建立的Line2D對象使用fig的座標,咱們將fig.TransFigure賦給Line2D對象的transform屬性;爲了 讓Line2D對象知道它是在fig對象中,咱們還設置其figure屬性爲fig;最後還須要將建立的兩個Line2D對象添加到fig.lines屬 性中去。
Figure對象有以下屬性包含其它的Artist對象:
Axes容器是整個matplotlib庫的核心,它包含了組成圖表的衆多Artist對象,而且有許多方法函數幫助咱們建立、修改這些對象。和 Figure同樣,它有一個patch屬性做爲背景,當它是笛卡爾座標時,patch屬性是一個Rectangle對象,而當它是極座標時,patch屬 性則是Circle對象(笛卡爾座標(幾何),極座標(角度))。例以下面的語句設置Axes對象的背景顏色爲綠色:
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> ax.patch.set_facecolor("green")
當你調用Axes的繪圖方法(例如plot,還有其餘麼?????),它將建立一組Line2D對象,並將全部的關鍵字參數傳遞給這些Line2D對象,並將它們添加進Axes.lines屬性中,最後返回所建立的Line2D對象列表:
>>> x, y = np.random.rand(2, 100)
>>> line, = ax.plot(x, y, "-", color="blue", linewidth=2)
>>> line
<matplotlib.lines.Line2D object at 0x03007030>
>>> ax.lines
[<matplotlib.lines.Line2D object at 0x03007030>]
注意plot返回的是一個Line2D對象的列表,由於咱們能夠傳遞多組X,Y軸的數據,一次繪製多條曲線。
與plot方法相似,繪製直方圖的方法bar和繪製柱狀統計圖的方法hist將建立一個Patch對象的列表,每一個元素實際上都是Patch的子類Rectangle,而且將所建立的Patch對象都添加進Axes.patches屬性中:
>>> ax = fig.add_subplot(111)
>>> n, bins, rects = ax.hist(np.random.randn(1000), 50, facecolor="blue")
>>> rects
<a list of 50 Patch objects>
>>> rects[0]
<matplotlib.patches.Rectangle object at 0x05BC2350>
>>> ax.patches[0]
<matplotlib.patches.Rectangle object at 0x05BC2350>
通常咱們不會直接對Axes.lines或者Axes.patches屬性進行操做,而是調用add_line或者add_patch等方法,這些方法幫助咱們完成許多屬性設置工做:
>>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> rect = matplotlib.patches.Rectangle((1,1), width=5, height=12) >>> print rect.get_axes() # rect的axes屬性爲空 None >>> rect.get_transform() # rect的transform屬性爲缺省值 BboxTransformTo(Bbox(array([[ 1., 1.], [ 6., 13.]]))) >>> ax.add_patch(rect) # 將rect添加進ax <matplotlib.patches.Rectangle object at 0x05C34E50> >>> rect.get_axes() # 因而rect的axes屬性就是ax <matplotlib.axes.AxesSubplot object at 0x05C09CB0>>>> # rect的transform屬性和ax的transData相同 >>> rect.get_transform() ... # 太長,省略 >>> ax.transData ... # 太長,省略>>> ax.get_xlim() # ax的X軸範圍爲0到1,沒法顯示完整的rect (0.0, 1.0) >>> ax.dataLim._get_bounds() # 數據的範圍和rect的大小一致 (1.0, 1.0, 5.0, 12.0) >>> ax.autoscale_view() # 自動調整座標軸範圍 >>> ax.get_xlim() # 因而X軸能夠完整顯示rect (1.0, 6.0) >>> plt.show()
經過上面的例子咱們能夠看出,add_patch方法幫助咱們設置了rect的axes和transform屬性。
下面詳細列出Axes包含各類Artist對象的屬性:
下面列出Axes的建立Artist對象的方法:
Axes的方法 | 所建立的對象 | 添加進的列表 |
annotate | Annotate | texts |
bars | Rectangle | patches |
errorbar | Line2D, Rectangle | lines,patches |
fill | Polygon | patches |
hist | Rectangle | patches |
imshow | AxesImage | images |
legend | Legend | legends |
plot | Line2D | lines |
scatter | PolygonCollection | Collections |
text | Text | texts |
下面以繪製散列圖(scatter)爲例,驗證一下:
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> t = ax.scatter(np.random.rand(20), np.random.rand(20))
>>> t # 返回值爲CircleCollection對象
<matplotlib.collections.CircleCollection object at 0x06004230>
>>> ax.collections # 返回的對象已經添加進了collections列表中
[<matplotlib.collections.CircleCollection object at 0x06004230>]
>>> fig.show()
>>> t.get_sizes() # 得到Collection的點數
20
圖5.5 用scatter函數繪製散列圖
Axis容器包括座標軸上的刻度線、刻度文本、座標網格以及座標軸標題等內容。刻度包括主刻度和副刻度,分別經過 Axis.get_major_ticks和Axis.get_minor_ticks方法得到。每一個刻度線都是一個XTick或者YTick對象,它包 括實際的刻度線和刻度文本。爲了方便訪問刻度線和文本,Axis對象提供了get_ticklabels和get_ticklines方法分別直接得到刻 度線和刻度文本:
>>> pl.plot([1,2,3],[4,5,6]) [<matplotlib.lines.Line2D object at 0x0AD3B670>] >>> pl.show() >>> axis = pl.gca().xaxis>>> axis.get_ticklocs() # 得到刻度的位置列表 array([ 1. , 1.5, 2. , 2.5, 3. ])>>> axis.get_ticklabels() # 得到刻度標籤列表 <a list of 5 Text major ticklabel objects> >>> [x.get_text() for x in axis.get_ticklabels()] # 得到刻度的文本字符串 [u'1.0', u'1.5', u'2.0', u'2.5', u'3.0']>>> axis.get_ticklines() # 得到主刻度線列表,圖的上下刻度線共10條 <a list of 10 Line2D ticklines objects>>>> axis.get_ticklines(minor=True) # 得到副刻度線列表 <a list of 0 Line2D ticklines objects>
得到刻度線或者刻度標籤以後,能夠設置其各類屬性,下面設置刻度線爲綠色粗線,文本爲紅色而且旋轉45度:
>>> for label in axis.get_ticklabels(): ... label.set_color("red") ... label.set_rotation(45) ... label.set_fontsize(16) ...>>> for line in axis.get_ticklines(): ... line.set_color("green") ... line.set_markersize(25) ... line.set_markeredgewidth(3)
最終的結果圖以下:
圖5.6 手工配置X軸的刻度線和刻度文本的樣式
上面的例子中,得到的副刻度線列表爲空,這是由於用於計算副刻度的對象缺省爲NullLocator,它不產生任何刻度線;而計算主刻度的對象爲AutoLocator,它會根據當前的縮放等配置自動計算刻度的位置:
>>> axis.get_minor_locator() # 計算副刻度的對象
<matplotlib.ticker.NullLocator instance at 0x0A014300>
>>> axis.get_major_locator() # 計算主刻度的對象
<matplotlib.ticker.AutoLocator instance at 0x09281B20>
咱們可使用程序爲Axis對象設置不一樣的Locator對象,用來手工設置刻度的位置;設置Formatter對象用來控制刻度文本的顯示。下面的程序設置X軸的主刻度爲pi/4,副刻度爲pi/20,而且主刻度上的文本以pi爲單位:
# -*- coding: utf-8 -*-
import matplotlib.pyplot as pl
from matplotlib.ticker import MultipleLocator, FuncFormatter
import numpy as np
x = np.arange(0, 4*np.pi, 0.01)
y = np.sin(x)
pl.figure(figsize=(8,4))
pl.plot(x, y)
ax = pl.gca()
def pi_formatter(x, pos):
"""
比較羅嗦地將數值轉換爲以pi/4爲單位的刻度文本
"""
m = np.round(x / (np.pi/4))
n = 4
if m%2==0: m, n = m/2, n/2
if m%2==0: m, n = m/2, n/2
if m == 0:
return "0"
if m == 1 and n == 1:
return "$\pi$"
if n == 1:
return r"$%d \pi$" % m
if m == 1:
return r"$\frac{\pi}{%d}$" % n
return r"$\frac{%d \pi}{%d}$" % (m,n)
# 設置兩個座標軸的範圍
pl.ylim(-1.5,1.5)
pl.xlim(0, np.max(x))
# 設置圖的底邊距
pl.subplots_adjust(bottom = 0.15)
pl.grid() #開啓網格
# 主刻度爲pi/4
ax.xaxis.set_major_locator( MultipleLocator(np.pi/4) )
# 主刻度文本用pi_formatter函數計算
ax.xaxis.set_major_formatter( FuncFormatter( pi_formatter ) )
# 副刻度爲pi/20
ax.xaxis.set_minor_locator( MultipleLocator(np.pi/20) )
# 設置刻度文本的大小
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_fontsize(16)
pl.show()
關於刻度的定位和文本格式的東西都在matplotlib.ticker中定義,程序中使用到以下兩個類:
此外還有不少預約義的Locator和Formatter類,詳細內容請參考相應的API文檔。
圖5.7 手工配置X軸的刻度線的位置和文本,並開啓副刻度