matplotlib 是python最著名的繪圖庫(kù),它提供了一整套和matlab相似的命令A(yù)PI,十分適合交互式地進(jìn)行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應(yīng)用程序中。 它的文檔相當(dāng)完備,并且 Gallery頁(yè)面 中有上百幅縮略圖,打開(kāi)之后都有源程序。因此如果你需要繪制某種類型的圖,只需要在這個(gè)頁(yè)面中瀏覽/復(fù)制/粘貼一下,基本上都能搞定。 本章節(jié)作為matplotlib的入門(mén)介紹,將較為深入地挖掘幾個(gè)例子,從中理解和學(xué)習(xí)matplotlib繪圖的一些基本概念。 5.1 快速繪圖
matplotlib的pyplot子庫(kù)提供了和matlab類似的繪圖API,方便用戶快速繪制2D圖表。讓我們先來(lái)看一個(gè)簡(jiǎn)單的例子: # -*- 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 調(diào)用pyplot庫(kù)快速將數(shù)據(jù)繪制成曲線圖 matplotlib中的快速繪圖的函數(shù)庫(kù)可以通過(guò)如下語(yǔ)句載入: import matplotlib.pyplot as plt pylab模塊 matplotlib還提供了名為pylab的模塊,其中包括了許多numpy和pyplot中常用的函數(shù),方便用戶快速進(jìn)行計(jì)算和繪圖,可以用于IPython中的快速交互式使用。 接下來(lái)調(diào)用figure創(chuàng)建一個(gè)繪圖對(duì)象,并且使它成為當(dāng)前的繪圖對(duì)象。 plt.figure(figsize=(8,4)) 也可以不創(chuàng)建繪圖對(duì)象直接調(diào)用接下來(lái)的plot函數(shù)直接繪圖,matplotlib會(huì)為我們自動(dòng)創(chuàng)建一個(gè)繪圖對(duì)象。如果需要同時(shí)繪制多幅圖表的話,可以是給figure傳遞一個(gè)整數(shù)參數(shù)指定圖標(biāo)的序號(hào),如果所指定序號(hào)的繪圖對(duì)象已經(jīng)存在的話,將不創(chuàng)建新的對(duì)象,而只是讓它成為當(dāng)前繪圖對(duì)象。 通過(guò)figsize參數(shù)可以指定繪圖對(duì)象的寬度和高度,單位為英寸;dpi參數(shù)指定繪圖對(duì)象的分辨率,即每英寸多少個(gè)像素,缺省值為80。因此本例中所創(chuàng)建的圖表窗口的寬度為8*80 = 640像素。 但是用工具欄中的保存按鈕保存下來(lái)的png圖像的大小是800*400像素。這是因?yàn)楸4鎴D表用的函數(shù)savefig使用不同的DPI配置,savefig函數(shù)也有一個(gè)dpi參數(shù),如果不設(shè)置的話,將使用matplotlib配置文件中的配置,此配置可以通過(guò)如下語(yǔ)句進(jìn)行查看,關(guān)于配置文件將在后面的章節(jié)進(jìn)行介紹: >>> import matplotlib >>> matplotlib.rcParams["savefig.dpi"] 100 下面的兩行程序通過(guò)調(diào)用plot函數(shù)在當(dāng)前的繪圖對(duì)象中進(jìn)行繪圖: plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2) plt.plot(x,z,"b--",label="$cos(x^2)$") plot函數(shù)的調(diào)用方式很靈活,第一句將x,y數(shù)組傳遞給plot之后,用關(guān)鍵字參數(shù)指定各種屬性:
第二句直接通過(guò)第三個(gè)參數(shù)"b--"指定曲線的顏色和線型,這個(gè)參數(shù)稱為格式化參數(shù),它能夠通過(guò)一些易記的符號(hào)快速指定曲線的樣式。其中b表示藍(lán)色,"--"表示線型為虛線。在IPython中輸入 "plt.plot?" 可以查看格式化字符串的詳細(xì)配置。 接下來(lái)通過(guò)一系列函數(shù)設(shè)置繪圖對(duì)象的各個(gè)屬性: plt.xlabel("Time(s)") plt.ylabel("Volt") plt.title("PyPlot First Example") plt.ylim(-1.2,1.2) plt.legend()
最后調(diào)用plt.show()顯示出我們創(chuàng)建的所有繪圖對(duì)象。 5.1.1 配置屬性
matplotlib所繪制的圖的每個(gè)組成部分都對(duì)應(yīng)有一個(gè)對(duì)象,我們可以通過(guò)調(diào)用這些對(duì)象的屬性設(shè)置方法set_*或者pyplot的屬性設(shè)置函數(shù)setp設(shè)置其屬性值。例如plot函數(shù)返回一個(gè) matplotlib.lines.Line2D 對(duì)象的列表,下面的例子顯示如何設(shè)置Line2D對(duì)象的屬性: >>> import numpy as np >>> import matplotlib.pyplot as plt >>> x = np.arange(0, 5, 0.1) >>> line, = plt.plot(x, x*x) # plot返回一個(gè)列表,通過(guò)line,獲取其第一個(gè)元素 >>> # 調(diào)用Line2D對(duì)象的set_*方法設(shè)置屬性值 >>> line.set_antialiased(False) >>> # 同時(shí)繪制sin和cos兩條曲線,lines是一個(gè)有兩個(gè)Line2D對(duì)象的列表 >>> lines = plt.plot(x, np.sin(x), x, np.cos(x)) # >>> # 調(diào)用setp函數(shù)同時(shí)配置多個(gè)Line2D對(duì)象的多個(gè)屬性值 >>> plt.setp(lines, color="r", linewidth=2.0) 這段例子中,通過(guò)調(diào)用Line2D對(duì)象line的set_antialiased方法,關(guān)閉對(duì)象的反鋸齒效果。或者通過(guò)調(diào)用plt.setp函數(shù)配置多個(gè)Line2D對(duì)象的顏色和線寬屬性。 同樣我們可以通過(guò)調(diào)用Line2D對(duì)象的get_*方法,或者plt.getp函數(shù)獲取對(duì)象的屬性值: >>> 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函數(shù)只能對(duì)一個(gè)對(duì)象進(jìn)行操作,它有兩種用法:
matplotlib的整個(gè)圖表為一個(gè)Figure對(duì)象,此對(duì)象在調(diào)用plt.figure函數(shù)時(shí)返回,我們也可以通過(guò)plt.gcf函數(shù)獲取當(dāng)前的繪圖對(duì)象: >>> f = plt.gcf() >>> plt.getp(f) alpha = 1.0 animated = False ... Figure對(duì)象有一個(gè)axes屬性,其值為AxesSubplot對(duì)象的列表,每個(gè)AxesSubplot對(duì)象代表圖表中的一個(gè)子圖,前面所繪制的圖表只包含一個(gè)子圖,當(dāng)前子圖也可以通過(guò)plt.gca獲得: >>> plt.getp(f, "axes") [<matplotlib.axes.AxesSubplot object at 0x05CDD170>] >>> plt.gca() <matplotlib.axes.AxesSubplot object at 0x05CDD170> 用plt.getp可以發(fā)現(xiàn)AxesSubplot對(duì)象有很多屬性,例如它的lines屬性為此子圖所包括的 Line2D 對(duì)象列表: >>> alllines = plt.getp(plt.gca(), "lines") >>> alllines <a list of 3 Line2D objects> >>> alllines[0] == line # 其中的第一條曲線就是最開(kāi)始繪制的那條曲線 True 通過(guò)這種方法我們可以很容易地查看對(duì)象的屬性和它們之間的包含關(guān)系,找到需要配置的屬性。 5.2 繪制多軸圖
一個(gè)繪圖對(duì)象(figure)可以包含多個(gè)軸(axis),在Matplotlib中用軸表示一個(gè)繪圖區(qū)域,可以將其理解為子圖。上面的第一個(gè)例子中,繪圖對(duì)象只包括一個(gè)軸,因此只顯示了一個(gè)軸(子圖)。我們可以使用subplot函數(shù)快速繪制有多個(gè)軸的圖表。subplot函數(shù)的調(diào)用形式如下: subplot(numRows, numCols, plotNum) subplot將整個(gè)繪圖區(qū)域等分為numRows行 * numCols列個(gè)子區(qū)域,然后按照從左到右,從上到下的順序?qū)γ總€(gè)子區(qū)域進(jìn)行編號(hào),左上的子區(qū)域的編號(hào)為1。如果numRows,numCols和plotNum這三個(gè)數(shù)都小于10的話,可以把它們縮寫(xiě)為一個(gè)整數(shù),例如subplot(323)和subplot(3,2,3)是相同的。subplot在plotNum指定的區(qū)域中創(chuàng)建一個(gè)軸對(duì)象。如果新創(chuàng)建的軸和之前創(chuàng)建的軸重疊的話,之前的軸將被刪除。 下面的程序創(chuàng)建3行2列共6個(gè)軸,通過(guò)axisbg參數(shù)給每個(gè)軸設(shè)置不同的背景顏色。 for idx, color in enumerate("rgbyck"): plt.subplot(320+idx+1, axisbg=color) plt.show() ![]() 圖5.2 用subplot函數(shù)將Figure分為六個(gè)子圖區(qū)域 如果希望某個(gè)軸占據(jù)整個(gè)行或者列的話,可以如下調(diào)用subplot: plt.subplot(221) # 第一行的左圖 plt.subplot(222) # 第一行的右圖 plt.subplot(212) # 第二整行 plt.show() ![]() 圖5.3 將Figure分為三個(gè)子圖區(qū)域 當(dāng)繪圖對(duì)象中有多個(gè)軸的時(shí)候,可以通過(guò)工具欄中的Configure Subplots按鈕,交互式地調(diào)節(jié)軸之間的間距和軸與邊框之間的距離。如果希望在程序中調(diào)節(jié)的話,可以調(diào)用subplots_adjust函數(shù),它有l(wèi)eft, right, bottom, top, wspace, hspace等幾個(gè)關(guān)鍵字參數(shù),這些參數(shù)的值都是0到1之間的小數(shù),它們是以繪圖區(qū)域的寬高為1進(jìn)行正規(guī)化之后的坐標(biāo)或者長(zhǎng)度。 5.3 配置文件
一幅圖有許多需要配置的屬性,例如顏色、字體、線型等等。我們?cè)诶L圖時(shí),并沒(méi)有一一對(duì)這些屬性進(jìn)行配置,許多都直接采用了Matplotlib的缺省配置。Matplotlib將缺省配置保存在一個(gè)文件中,通過(guò)更改這個(gè)文件,我們可以修改這些屬性的缺省值。 Matplotlib 使用配置文件 matplotlibrc 時(shí)的搜索順序如下:
通過(guò)下面的語(yǔ)句可以獲取用戶配置路徑: >>> import matplotlib >>> matplotlib.get_configdir() 'C:\\Documents and Settings\\zhang\\.matplotlib' 通過(guò)下面的語(yǔ)句可以獲得目前使用的配置文件的路徑: >>> import matplotlib >>> matplotlib.matplotlib_fname() 'C:\\Python26\\lib\\site-packages\\matplotlib\\mpl-data\\matplotlibrc' 由于在當(dāng)前路徑和用戶配置路徑中都沒(méi)有找到位置文件,因此最后使用的是系統(tǒng)配置路徑下的配置文件。如果你將matplotlibrc復(fù)制一份到腳本的當(dāng)前目錄下: >>> import os >>> os.getcwd() 'C:\\zhang\\doc' 復(fù)制配置文件之后再運(yùn)行: >>> matplotlib.matplotlib_fname() 'C:\\zhang\\doc\\matplotlibrc' 如果你用文本編輯器打開(kāi)此配置文件的話,你會(huì)發(fā)現(xiàn)它實(shí)際上是定義了一個(gè)字典。為了對(duì)眾多的配置進(jìn)行區(qū)分,關(guān)鍵字可以用點(diǎn)分開(kāi)。 配置文件的讀入可以使用 rc_params 函數(shù),它返回一個(gè)配置字典: >>> matplotlib.rc_params() {'agg.path.chunksize': 0, 'axes.axisbelow': False, 'axes.edgecolor': 'k', 'axes.facecolor': 'w', ... ... 在matplotlib模塊載入的時(shí)候會(huì)調(diào)用rc_params,并把得到的配置字典保存到rcParams變量中: >>> matplotlib.rcParams {'agg.path.chunksize': 0, 'axes.axisbelow': False, ... ... matplotlib將使用rcParams中的配置進(jìn)行繪圖。用戶可以直接修改此字典中的配置,所做的改變會(huì)反映到此后所繪制的圖中。例如下面的腳本所繪制的線將帶有圓形的點(diǎn)標(biāo)識(shí)符: >>> matplotlib.rcParams["lines.marker"] = "o" >>> import pylab >>> pylab.plot([1,2,3]) >>> pylab.show() 為了方便配置,可以使用rc函數(shù),下面的例子同時(shí)配置點(diǎn)標(biāo)識(shí)符、線寬和顏色: >>> matplotlib.rc("lines", marker="x", linewidth=2, color="red") 如果希望恢復(fù)到缺省的配置(matplotlib載入時(shí)從配置文件讀入的配置)的話,可以調(diào)用 rcdefaults 函數(shù)。 >>> matplotlib.rcdefaults() 如果手工修改了配置文件,希望重新從配置文件載入最新的配置的話,可以調(diào)用: >>> matplotlib.rcParams.update( matplotlib.rc_params() ) 5.4 Artist對(duì)象
matplotlib API包含有三層:
FigureCanvas和Renderer需要處理底層的繪圖操作,例如使用wxPython在界面上繪圖,或者使用PostScript繪制PDF。Artist則處理所有的高層結(jié)構(gòu),例如處理圖表、文字和曲線等的繪制和布局。通常我們只和Artist打交道,而不需要關(guān)心底層的繪制細(xì)節(jié)。 Artists分為簡(jiǎn)單類型和容器類型兩種。簡(jiǎn)單類型的Artists為標(biāo)準(zhǔn)的繪圖元件,例如Line2D、 Rectangle、 Text、AxesImage 等等。而容器類型則可以包含許多簡(jiǎn)單類型的Artists,使它們組織成一個(gè)整體,例如Axis、 Axes、Figure等。 直接使用Artists創(chuàng)建圖表的標(biāo)準(zhǔn)流程如下:
下面首先調(diào)用pyplot.figure輔助函數(shù)創(chuàng)建Figure對(duì)象,然后調(diào)用Figure對(duì)象的add_axes方法在其中創(chuàng)建一個(gè)Axes對(duì)象,add_axes的參數(shù)是一個(gè)形如[left, bottom, width, height]的列表,這些數(shù)值分別指定所創(chuàng)建的Axes對(duì)象相對(duì)于fig的位置和大小,取值范圍都在0到1之間: >>> import matplotlib.pyplot as plt >>> fig = plt.figure() >>> ax = fig.add_axes([0.15, 0.1, 0.7, 0.3]) 然后我們調(diào)用ax的plot方法繪圖,創(chuàng)建一條曲線,并且返回此曲線對(duì)象(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是一個(gè)為包含ax的所有曲線的列表,后續(xù)的ax.plot調(diào)用會(huì)往此列表中添加新的曲線。如果想刪除某條曲線的話,直接從此列表中刪除即可。 Axes對(duì)象還包括許多其它的Artists對(duì)象,例如我們可以通過(guò)調(diào)用set_xlabel設(shè)置其X軸上的標(biāo)題: >>> ax.set_xlabel("time") 如果我們查看set_xlabel的源代碼的話,會(huì)發(fā)現(xiàn)它是通過(guò)調(diào)用下面的語(yǔ)句實(shí)現(xiàn)的: self.xaxis.set_label_text(xlabel) 如果我們一直跟蹤下去,會(huì)發(fā)現(xiàn)Axes的xaxis屬性是一個(gè)XAxis對(duì)象: >>> ax.xaxis <matplotlib.axis.XAxis object at 0x06343230> XAxis的label屬性是一個(gè)Text對(duì)象: >>> ax.xaxis.label <matplotlib.text.Text object at 0x06343290> 而Text對(duì)象的_text屬性為我們?cè)O(shè)置的值: >>> ax.xaxis.label._text 'time' 這些對(duì)象都是Artists,因此也可以調(diào)用它們的屬性獲取函數(shù)來(lái)獲得相應(yīng)的屬性: >>> ax.xaxis.label.get_text() 'time' 5.4.1 Artist的屬性
圖表中的每個(gè)元素都用一個(gè)matplotlib的Artist對(duì)象表示,而每個(gè)Artist對(duì)象都有一大堆屬性控制其顯示效果。例如Figure對(duì)象和Axes對(duì)象都有patch屬性作為其背景,它的值是一個(gè)Rectangle對(duì)象。通過(guò)設(shè)置此它的一些屬性可以修改Figrue圖表的背景顏色或者透明度等屬性,下面的例子將圖表的背景顏色設(shè)置為綠色: >>> fig = plt.figure() >>> fig.show() >>> fig.patch.set_color("g") >>> fig.canvas.draw() patch的color屬性通過(guò)set_color函數(shù)進(jìn)行設(shè)置,屬性修改之后并不會(huì)立即反映到圖表的顯示上,還需要調(diào)用fig.canvas.draw()函數(shù)才能夠更新顯示。 下面是Artist對(duì)象都具有的一些屬性:
Artist對(duì)象的所有屬性都通過(guò)相應(yīng)的 get_* 和 set_* 函數(shù)進(jìn)行讀寫(xiě),例如下面的語(yǔ)句將alpha屬性設(shè)置為當(dāng)前值的一半: >>> fig.set_alpha(0.5*fig.get_alpha()) 如果你想用一條語(yǔ)句設(shè)置多個(gè)屬性的話,可以使用set函數(shù): >>> fig.set(alpha=0.5, zorder=2) 使用前面介紹的 matplotlib.pyplot.getp 函數(shù)可以方便地輸出Artist對(duì)象的所有屬性名和值。 >>> plt.getp(fig.patch) aa = True alpha = 1.0 animated = False antialiased or aa = True ... ... 5.4.2 Figure容器
現(xiàn)在我們知道如何觀察和修改已知的某個(gè)Artist對(duì)象的屬性,接下來(lái)要解決如何找到指定的Artist對(duì)象。前面我們介紹過(guò)Artist對(duì)象有容器類型和簡(jiǎn)單類型兩種,這一節(jié)讓我們來(lái)詳細(xì)看看容器類型的內(nèi)容。 最大的Artist容器是matplotlib.figure.Figure,它包括組成圖表的所有元素。圖表的背景是一個(gè)Rectangle對(duì)象,用Figure.patch屬性表示。當(dāng)你通過(guò)調(diào)用add_subplot或者add_axes方法往圖表中添加軸(子圖時(shí)),這些子圖都將添加到Figure.axes屬性中,同時(shí)這兩個(gè)方法也返回添加進(jìn)axes屬性的對(duì)象,注意返回值的類型有所不同,實(shí)際上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()等函數(shù),F(xiàn)igure對(duì)象內(nèi)部保存有當(dāng)前軸的信息,因此不建議直接對(duì)Figure.axes屬性進(jìn)行列表操作,而應(yīng)該使用add_subplot, add_axes, delaxes等方法進(jìn)行添加和刪除操作。但是使用for循環(huán)對(duì)axes中的每個(gè)元素進(jìn)行操作是沒(méi)有問(wèn)題的,下面的語(yǔ)句打開(kāi)所有子圖的柵格。 >>> for ax in fig.axes: ax.grid(True) Figure對(duì)象可以擁有自己的文字、線條以及圖像等簡(jiǎn)單類型的Artist。缺省的坐標(biāo)系統(tǒng)為像素點(diǎn),但是可以通過(guò)設(shè)置Artist對(duì)象的transform屬性修改坐標(biāo)系的轉(zhuǎn)換方式。最常用的Figure對(duì)象的坐標(biāo)系是以左下角為坐標(biāo)原點(diǎn)(0,0),右上角為坐標(biāo)(1,1)。下面的程序創(chuàng)建并添加兩條直線到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對(duì)象中手工繪制直線 注意為了讓所創(chuàng)建的Line2D對(duì)象使用fig的坐標(biāo),我們將fig.TransFigure賦給Line2D對(duì)象的transform屬性;為了讓Line2D對(duì)象知道它是在fig對(duì)象中,我們還設(shè)置其figure屬性為fig;最后還需要將創(chuàng)建的兩個(gè)Line2D對(duì)象添加到fig.lines屬性中去。 Figure對(duì)象有如下屬性包含其它的Artist對(duì)象:
5.4.3 Axes容器
Axes容器是整個(gè)matplotlib庫(kù)的核心,它包含了組成圖表的眾多Artist對(duì)象,并且有許多方法函數(shù)幫助我們創(chuàng)建、修改這些對(duì)象。和Figure一樣,它有一個(gè)patch屬性作為背景,當(dāng)它是笛卡爾坐標(biāo)時(shí),patch屬性是一個(gè)Rectangle對(duì)象,而當(dāng)它是極坐標(biāo)時(shí),patch屬性則是Circle對(duì)象。例如下面的語(yǔ)句設(shè)置Axes對(duì)象的背景顏色為綠色: >>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> ax.patch.set_facecolor("green") 當(dāng)你調(diào)用Axes的繪圖方法(例如plot),它將創(chuàng)建一組Line2D對(duì)象,并將所有的關(guān)鍵字參數(shù)傳遞給這些Line2D對(duì)象,并將它們添加進(jìn)Axes.lines屬性中,最后返回所創(chuàng)建的Line2D對(duì)象列表: >>> 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返回的是一個(gè)Line2D對(duì)象的列表,因?yàn)槲覀兛梢詡鬟f多組X,Y軸的數(shù)據(jù),一次繪制多條曲線。 與plot方法類似,繪制直方圖的方法bar和繪制柱狀統(tǒng)計(jì)圖的方法hist將創(chuàng)建一個(gè)Patch對(duì)象的列表,每個(gè)元素實(shí)際上都是Patch的子類Rectangle,并且將所創(chuàng)建的Patch對(duì)象都添加進(jìn)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> 一般我們不會(huì)直接對(duì)Axes.lines或者Axes.patches屬性進(jìn)行操作,而是調(diào)用add_line或者add_patch等方法,這些方法幫助我們完成許多屬性設(shè)置工作:
通過(guò)上面的例子我們可以看出,add_patch方法幫助我們?cè)O(shè)置了rect的axes和transform屬性。 下面詳細(xì)列出Axes包含各種Artist對(duì)象的屬性:
下面列出Axes的創(chuàng)建Artist對(duì)象的方法:
下面以繪制散列圖(scatter)為例,驗(yàn)證一下: >>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> t = ax.scatter(np.random.rand(20), np.random.rand(20)) >>> t # 返回值為CircleCollection對(duì)象 <matplotlib.collections.CircleCollection object at 0x06004230> >>> ax.collections # 返回的對(duì)象已經(jīng)添加進(jìn)了collections列表中 [<matplotlib.collections.CircleCollection object at 0x06004230>] >>> fig.show() >>> t.get_sizes() # 獲得Collection的點(diǎn)數(shù) 20 ![]() 圖5.5 用scatter函數(shù)繪制散列圖 5.4.4 Axis容器
Axis容器包括坐標(biāo)軸上的刻度線、刻度文本、坐標(biāo)網(wǎng)格以及坐標(biāo)軸標(biāo)題等內(nèi)容。刻度包括主刻度和副刻度,分別通過(guò)Axis.get_major_ticks和Axis.get_minor_ticks方法獲得。每個(gè)刻度線都是一個(gè)XTick或者YTick對(duì)象,它包括實(shí)際的刻度線和刻度文本。為了方便訪問(wèn)刻度線和文本,Axis對(duì)象提供了get_ticklabels和get_ticklines方法分別直接獲得刻度線和刻度文本:
獲得刻度線或者刻度標(biāo)簽之后,可以設(shè)置其各種屬性,下面設(shè)置刻度線為綠色粗線,文本為紅色并且旋轉(zhuǎn)45度:
最終的結(jié)果圖如下: ![]() 圖5.6 手工配置X軸的刻度線和刻度文本的樣式 上面的例子中,獲得的副刻度線列表為空,這是因?yàn)橛糜谟?jì)算副刻度的對(duì)象缺省為NullLocator,它不產(chǎn)生任何刻度線;而計(jì)算主刻度的對(duì)象為AutoLocator,它會(huì)根據(jù)當(dāng)前的縮放等配置自動(dòng)計(jì)算刻度的位置: >>> axis.get_minor_locator() # 計(jì)算副刻度的對(duì)象 <matplotlib.ticker.NullLocator instance at 0x0A014300> >>> axis.get_major_locator() # 計(jì)算主刻度的對(duì)象 <matplotlib.ticker.AutoLocator instance at 0x09281B20> 我們可以使用程序?yàn)锳xis對(duì)象設(shè)置不同的Locator對(duì)象,用來(lái)手工設(shè)置刻度的位置;設(shè)置Formatter對(duì)象用來(lái)控制刻度文本的顯示。下面的程序設(shè)置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): """ 比較羅嗦地將數(shù)值轉(zhuǎn)換為以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) # 設(shè)置兩個(gè)坐標(biāo)軸的范圍 pl.ylim(-1.5,1.5) pl.xlim(0, np.max(x)) # 設(shè)置圖的底邊距 pl.subplots_adjust(bottom = 0.15) pl.grid() #開(kāi)啟網(wǎng)格 # 主刻度為pi/4 ax.xaxis.set_major_locator( MultipleLocator(np.pi/4) ) # 主刻度文本用pi_formatter函數(shù)計(jì)算 ax.xaxis.set_major_formatter( FuncFormatter( pi_formatter ) ) # 副刻度為pi/20 ax.xaxis.set_minor_locator( MultipleLocator(np.pi/20) ) # 設(shè)置刻度文本的大小 for tick in ax.xaxis.get_major_ticks(): tick.label1.set_fontsize(16) pl.show() 關(guān)于刻度的定位和文本格式的東西都在matplotlib.ticker中定義,程序中使用到如下兩個(gè)類:
此外還有很多預(yù)定義的Locator和Formatter類,詳細(xì)內(nèi)容請(qǐng)參考相應(yīng)的API文檔。 ![]() 圖5.7 手工配置X軸的刻度線的位置和文本,并開(kāi)啟副刻度 |
|
來(lái)自: 易小丫丫 > 《程序語(yǔ)言》