乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      matplotlib

       易小丫丫 2013-02-28

      matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的命令A(yù)PI,十分適合交互式地進行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應(yīng)用程序中。

      它的文檔相當(dāng)完備,并且 Gallery頁面 中有上百幅縮略圖,打開之后都有源程序。因此如果你需要繪制某種類型的圖,只需要在這個頁面中瀏覽/復(fù)制/粘貼一下,基本上都能搞定。

      本章節(jié)作為matplotlib的入門介紹,將較為深入地挖掘幾個例子,從中理解和學(xué)習(xí)matplotlib繪圖的一些基本概念。

      5.1 快速繪圖

      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()
      
      _images/pyplot_simple_plot.png

      圖5.1 調(diào)用pyplot庫快速將數(shù)據(jù)繪制成曲線圖

      matplotlib中的快速繪圖的函數(shù)庫可以通過如下語句載入:

      import matplotlib.pyplot as plt
      

      pylab模塊

      matplotlib還提供了名為pylab的模塊,其中包括了許多numpy和pyplot中常用的函數(shù),方便用戶快速進行計算和繪圖,可以用于IPython中的快速交互式使用。

      接下來調(diào)用figure創(chuàng)建一個繪圖對象,并且使它成為當(dāng)前的繪圖對象。

      plt.figure(figsize=(8,4))
      

      也可以不創(chuàng)建繪圖對象直接調(diào)用接下來的plot函數(shù)直接繪圖,matplotlib會為我們自動創(chuàng)建一個繪圖對象。如果需要同時繪制多幅圖表的話,可以是給figure傳遞一個整數(shù)參數(shù)指定圖標(biāo)的序號,如果所指定序號的繪圖對象已經(jīng)存在的話,將不創(chuàng)建新的對象,而只是讓它成為當(dāng)前繪圖對象。

      通過figsize參數(shù)可以指定繪圖對象的寬度和高度,單位為英寸;dpi參數(shù)指定繪圖對象的分辨率,即每英寸多少個像素,缺省值為80。因此本例中所創(chuàng)建的圖表窗口的寬度為8*80 = 640像素。

      但是用工具欄中的保存按鈕保存下來的png圖像的大小是800*400像素。這是因為保存圖表用的函數(shù)savefig使用不同的DPI配置,savefig函數(shù)也有一個dpi參數(shù),如果不設(shè)置的話,將使用matplotlib配置文件中的配置,此配置可以通過如下語句進行查看,關(guān)于配置文件將在后面的章節(jié)進行介紹:

      >>> import matplotlib
      >>> matplotlib.rcParams["savefig.dpi"]
      100
      

      下面的兩行程序通過調(diào)用plot函數(shù)在當(dāng)前的繪圖對象中進行繪圖:

      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ù)指定各種屬性:

      • label : 給所繪制的曲線一個名字,此名字在圖示(legend)中顯示。只要在字符串前后添加"$"符號,matplotlib就會使用其內(nèi)嵌的latex引擎繪制的數(shù)學(xué)公式。
      • color : 指定曲線的顏色
      • linewidth : 指定曲線的寬度

      第二句直接通過第三個參數(shù)"b--"指定曲線的顏色和線型,這個參數(shù)稱為格式化參數(shù),它能夠通過一些易記的符號快速指定曲線的樣式。其中b表示藍(lán)色,"--"表示線型為虛線。在IPython中輸入 "plt.plot?" 可以查看格式化字符串的詳細(xì)配置。

      接下來通過一系列函數(shù)設(shè)置繪圖對象的各個屬性:

      plt.xlabel("Time(s)")
      plt.ylabel("Volt")
      plt.title("PyPlot First Example")
      plt.ylim(-1.2,1.2)
      plt.legend()
      
      • xlabel : 設(shè)置X軸的文字
      • ylabel : 設(shè)置Y軸的文字
      • title : 設(shè)置圖表的標(biāo)題
      • ylim : 設(shè)置Y軸的范圍
      • legend : 顯示圖示

      最后調(diào)用plt.show()顯示出我們創(chuàng)建的所有繪圖對象。

      5.1.1 配置屬性

      matplotlib所繪制的圖的每個組成部分都對應(yīng)有一個對象,我們可以通過調(diào)用這些對象的屬性設(shè)置方法set_*或者pyplot的屬性設(shè)置函數(shù)setp設(shè)置其屬性值。例如plot函數(shù)返回一個 matplotlib.lines.Line2D 對象的列表,下面的例子顯示如何設(shè)置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,獲取其第一個元素
      >>> # 調(diào)用Line2D對象的set_*方法設(shè)置屬性值
      >>> line.set_antialiased(False)
      
      >>> # 同時繪制sin和cos兩條曲線,lines是一個有兩個Line2D對象的列表
      >>> lines = plt.plot(x, np.sin(x), x, np.cos(x)) #
      >>> # 調(diào)用setp函數(shù)同時配置多個Line2D對象的多個屬性值
      >>> plt.setp(lines, color="r", linewidth=2.0)
      

      這段例子中,通過調(diào)用Line2D對象line的set_antialiased方法,關(guān)閉對象的反鋸齒效果。或者通過調(diào)用plt.setp函數(shù)配置多個Line2D對象的顏色和線寬屬性。

      同樣我們可以通過調(diào)用Line2D對象的get_*方法,或者plt.getp函數(shù)獲取對象的屬性值:

      >>> 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ù)只能對一個對象進行操作,它有兩種用法:

      • 指定屬性名:返回對象的指定屬性的值
      • 不指定屬性名:打印出對象的所有屬性和其值

      matplotlib的整個圖表為一個Figure對象,此對象在調(diào)用plt.figure函數(shù)時返回,我們也可以通過plt.gcf函數(shù)獲取當(dāng)前的繪圖對象:

      >>> f = plt.gcf()
      >>> plt.getp(f)
      alpha = 1.0
      animated = False
      ...
      

      Figure對象有一個axes屬性,其值為AxesSubplot對象的列表,每個AxesSubplot對象代表圖表中的一個子圖,前面所繪制的圖表只包含一個子圖,當(dāng)前子圖也可以通過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對象有很多屬性,例如它的lines屬性為此子圖所包括的 Line2D 對象列表:

      >>> alllines = plt.getp(plt.gca(), "lines")
      >>> alllines
      <a list of 3 Line2D objects>
      >>> alllines[0] == line # 其中的第一條曲線就是最開始繪制的那條曲線
      True
      

      通過這種方法我們可以很容易地查看對象的屬性和它們之間的包含關(guān)系,找到需要配置的屬性。

      5.2 繪制多軸圖

      一個繪圖對象(figure)可以包含多個軸(axis),在Matplotlib中用軸表示一個繪圖區(qū)域,可以將其理解為子圖。上面的第一個例子中,繪圖對象只包括一個軸,因此只顯示了一個軸(子圖)。我們可以使用subplot函數(shù)快速繪制有多個軸的圖表。subplot函數(shù)的調(diào)用形式如下:

      subplot(numRows, numCols, plotNum)
      

      subplot將整個繪圖區(qū)域等分為numRows行 * numCols列個子區(qū)域,然后按照從左到右,從上到下的順序?qū)γ總€子區(qū)域進行編號,左上的子區(qū)域的編號為1。如果numRows,numCols和plotNum這三個數(shù)都小于10的話,可以把它們縮寫為一個整數(shù),例如subplot(323)和subplot(3,2,3)是相同的。subplot在plotNum指定的區(qū)域中創(chuàng)建一個軸對象。如果新創(chuàng)建的軸和之前創(chuàng)建的軸重疊的話,之前的軸將被刪除。

      下面的程序創(chuàng)建3行2列共6個軸,通過axisbg參數(shù)給每個軸設(shè)置不同的背景顏色。

      for idx, color in enumerate("rgbyck"):
          plt.subplot(320+idx+1, axisbg=color)
      plt.show()
      
      _images/pyplot_subplot01.png

      圖5.2 用subplot函數(shù)將Figure分為六個子圖區(qū)域

      如果希望某個軸占據(jù)整個行或者列的話,可以如下調(diào)用subplot:

      plt.subplot(221) # 第一行的左圖
      plt.subplot(222) # 第一行的右圖
      plt.subplot(212) # 第二整行
      plt.show()
      
      _images/pyplot_subplot02.png

      圖5.3 將Figure分為三個子圖區(qū)域

      當(dāng)繪圖對象中有多個軸的時候,可以通過工具欄中的Configure Subplots按鈕,交互式地調(diào)節(jié)軸之間的間距和軸與邊框之間的距離。如果希望在程序中調(diào)節(jié)的話,可以調(diào)用subplots_adjust函數(shù),它有l(wèi)eft, right, bottom, top, wspace, hspace等幾個關(guān)鍵字參數(shù),這些參數(shù)的值都是0到1之間的小數(shù),它們是以繪圖區(qū)域的寬高為1進行正規(guī)化之后的坐標(biāo)或者長度。

      5.3 配置文件

      一幅圖有許多需要配置的屬性,例如顏色、字體、線型等等。我們在繪圖時,并沒有一一對這些屬性進行配置,許多都直接采用了Matplotlib的缺省配置。Matplotlib將缺省配置保存在一個文件中,通過更改這個文件,我們可以修改這些屬性的缺省值。

      Matplotlib 使用配置文件 matplotlibrc 時的搜索順序如下:

      • 當(dāng)前路徑 : 程序的當(dāng)前路徑
      • 用戶配置路徑 : 通常為 HOME/.matplotlib/,可以通過環(huán)境變量MATPLOTLIBRC修改
      • 系統(tǒng)配置路徑 : 保存在 matplotlib的安裝目錄下的 mpl-data 下

      通過下面的語句可以獲取用戶配置路徑:

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

      由于在當(dāng)前路徑和用戶配置路徑中都沒有找到位置文件,因此最后使用的是系統(tǒng)配置路徑下的配置文件。如果你將matplotlibrc復(fù)制一份到腳本的當(dāng)前目錄下:

      >>> import os
      >>> os.getcwd()
      'C:\\zhang\\doc'
      

      復(fù)制配置文件之后再運行:

      >>> matplotlib.matplotlib_fname()
      'C:\\zhang\\doc\\matplotlibrc'
      

      如果你用文本編輯器打開此配置文件的話,你會發(fā)現(xiàn)它實際上是定義了一個字典。為了對眾多的配置進行區(qū)分,關(guān)鍵字可以用點分開。

      配置文件的讀入可以使用 rc_params 函數(shù),它返回一個配置字典:

      >>> matplotlib.rc_params()
      {'agg.path.chunksize': 0,
       'axes.axisbelow': False,
       'axes.edgecolor': 'k',
       'axes.facecolor': 'w',
       ... ...
      

      在matplotlib模塊載入的時候會調(diào)用rc_params,并把得到的配置字典保存到rcParams變量中:

      >>> matplotlib.rcParams
      {'agg.path.chunksize': 0,
      'axes.axisbelow': False,
      ... ...
      

      matplotlib將使用rcParams中的配置進行繪圖。用戶可以直接修改此字典中的配置,所做的改變會反映到此后所繪制的圖中。例如下面的腳本所繪制的線將帶有圓形的點標(biāo)識符:

      >>> matplotlib.rcParams["lines.marker"] = "o"
      >>> import pylab
      >>> pylab.plot([1,2,3])
      >>> pylab.show()
      

      為了方便配置,可以使用rc函數(shù),下面的例子同時配置點標(biāo)識符、線寬和顏色:

      >>> matplotlib.rc("lines", marker="x", linewidth=2, color="red")
      

      如果希望恢復(fù)到缺省的配置(matplotlib載入時從配置文件讀入的配置)的話,可以調(diào)用 rcdefaults 函數(shù)。

      >>> matplotlib.rcdefaults()
      

      如果手工修改了配置文件,希望重新從配置文件載入最新的配置的話,可以調(diào)用:

      >>> matplotlib.rcParams.update( matplotlib.rc_params() )
      

      5.4 Artist對象

      matplotlib API包含有三層:

      • backend_bases.FigureCanvas : 圖表的繪制領(lǐng)域
      • backend_bases.Renderer : 知道如何在FigureCanvas上如何繪圖
      • artist.Artist : 知道如何使用Renderer在FigureCanvas上繪圖

      FigureCanvas和Renderer需要處理底層的繪圖操作,例如使用wxPython在界面上繪圖,或者使用PostScript繪制PDF。Artist則處理所有的高層結(jié)構(gòu),例如處理圖表、文字和曲線等的繪制和布局。通常我們只和Artist打交道,而不需要關(guān)心底層的繪制細(xì)節(jié)。

      Artists分為簡單類型和容器類型兩種。簡單類型的Artists為標(biāo)準(zhǔn)的繪圖元件,例如Line2D、 Rectangle、 Text、AxesImage 等等。而容器類型則可以包含許多簡單類型的Artists,使它們組織成一個整體,例如Axis、 Axes、Figure等。

      直接使用Artists創(chuàng)建圖表的標(biāo)準(zhǔn)流程如下:

      • 創(chuàng)建Figure對象
      • 用Figure對象創(chuàng)建一個或者多個Axes或者Subplot對象
      • 調(diào)用Axies等對象的方法創(chuàng)建各種簡單類型的Artists

      下面首先調(diào)用pyplot.figure輔助函數(shù)創(chuàng)建Figure對象,然后調(diào)用Figure對象的add_axes方法在其中創(chuàng)建一個Axes對象,add_axes的參數(shù)是一個形如[left, bottom, width, height]的列表,這些數(shù)值分別指定所創(chuàng)建的Axes對象相對于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)建一條曲線,并且返回此曲線對象(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的所有曲線的列表,后續(xù)的ax.plot調(diào)用會往此列表中添加新的曲線。如果想刪除某條曲線的話,直接從此列表中刪除即可。

      Axes對象還包括許多其它的Artists對象,例如我們可以通過調(diào)用set_xlabel設(shè)置其X軸上的標(biāo)題:

      >>> ax.set_xlabel("time")
      

      如果我們查看set_xlabel的源代碼的話,會發(fā)現(xiàn)它是通過調(diào)用下面的語句實現(xiàn)的:

      self.xaxis.set_label_text(xlabel)
      

      如果我們一直跟蹤下去,會發(fā)現(xiàn)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屬性為我們設(shè)置的值:

      >>> ax.xaxis.label._text
      'time'
      

      這些對象都是Artists,因此也可以調(diào)用它們的屬性獲取函數(shù)來獲得相應(yīng)的屬性:

      >>> ax.xaxis.label.get_text()
      'time'
      

      5.4.1 Artist的屬性

      圖表中的每個元素都用一個matplotlib的Artist對象表示,而每個Artist對象都有一大堆屬性控制其顯示效果。例如Figure對象和Axes對象都有patch屬性作為其背景,它的值是一個Rectangle對象。通過設(shè)置此它的一些屬性可以修改Figrue圖表的背景顏色或者透明度等屬性,下面的例子將圖表的背景顏色設(shè)置為綠色:

      >>> fig = plt.figure()
      >>> fig.show()
      >>> fig.patch.set_color("g")
      >>> fig.canvas.draw()
      

      patch的color屬性通過set_color函數(shù)進行設(shè)置,屬性修改之后并不會立即反映到圖表的顯示上,還需要調(diào)用fig.canvas.draw()函數(shù)才能夠更新顯示。

      下面是Artist對象都具有的一些屬性:

      • alpha : 透明度,值在0到1之間,0為完全透明,1為完全不透明
      • animated : 布爾值,在繪制動畫效果時使用
      • axes : 此Artist對象所在的Axes對象,可能為None
      • clip_box : 對象的裁剪框
      • clip_on : 是否裁剪
      • clip_path : 裁剪的路徑
      • contains : 判斷指定點是否在對象上的函數(shù)
      • figure : 所在的Figure對象,可能為None
      • label : 文本標(biāo)簽
      • picker : 控制Artist對象選取
      • transform : 控制偏移旋轉(zhuǎn)
      • visible : 是否可見
      • zorder : 控制繪圖順序

      Artist對象的所有屬性都通過相應(yīng)的 get_* 和 set_* 函數(shù)進行讀寫,例如下面的語句將alpha屬性設(shè)置為當(dāng)前值的一半:

      >>> fig.set_alpha(0.5*fig.get_alpha())
      

      如果你想用一條語句設(shè)置多個屬性的話,可以使用set函數(shù):

      >>> fig.set(alpha=0.5, zorder=2)
      

      使用前面介紹的 matplotlib.pyplot.getp 函數(shù)可以方便地輸出Artist對象的所有屬性名和值。

      >>> plt.getp(fig.patch)
          aa = True
          alpha = 1.0
          animated = False
          antialiased or aa = True
          ... ...
      

      5.4.2 Figure容器

      現(xiàn)在我們知道如何觀察和修改已知的某個Artist對象的屬性,接下來要解決如何找到指定的Artist對象。前面我們介紹過Artist對象有容器類型和簡單類型兩種,這一節(jié)讓我們來詳細(xì)看看容器類型的內(nèi)容。

      最大的Artist容器是matplotlib.figure.Figure,它包括組成圖表的所有元素。圖表的背景是一個Rectangle對象,用Figure.patch屬性表示。當(dāng)你通過調(diào)用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()等函數(shù),F(xiàn)igure對象內(nèi)部保存有當(dāng)前軸的信息,因此不建議直接對Figure.axes屬性進行列表操作,而應(yīng)該使用add_subplot, add_axes, delaxes等方法進行添加和刪除操作。但是使用for循環(huán)對axes中的每個元素進行操作是沒有問題的,下面的語句打開所有子圖的柵格。

      >>> for ax in fig.axes: ax.grid(True)
      

      Figure對象可以擁有自己的文字、線條以及圖像等簡單類型的Artist。缺省的坐標(biāo)系統(tǒng)為像素點,但是可以通過設(shè)置Artist對象的transform屬性修改坐標(biāo)系的轉(zhuǎn)換方式。最常用的Figure對象的坐標(biāo)系是以左下角為坐標(biāo)原點(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()
      
      _images/pyplot_artist01.png

      圖5.4 在Figure對象中手工繪制直線

      注意為了讓所創(chuàng)建的Line2D對象使用fig的坐標(biāo),我們將fig.TransFigure賦給Line2D對象的transform屬性;為了讓Line2D對象知道它是在fig對象中,我們還設(shè)置其figure屬性為fig;最后還需要將創(chuàng)建的兩個Line2D對象添加到fig.lines屬性中去。

      Figure對象有如下屬性包含其它的Artist對象:

      • axes : Axes對象列表
      • patch : 作為背景的Rectangle對象
      • images : FigureImage對象列表,用來顯示圖片
      • legends : Legend對象列表
      • lines : Line2D對象列表
      • patches : patch對象列表
      • texts : Text對象列表,用來顯示文字

      5.4.3 Axes容器

      Axes容器是整個matplotlib庫的核心,它包含了組成圖表的眾多Artist對象,并且有許多方法函數(shù)幫助我們創(chuàng)建、修改這些對象。和Figure一樣,它有一個patch屬性作為背景,當(dāng)它是笛卡爾坐標(biāo)時,patch屬性是一個Rectangle對象,而當(dāng)它是極坐標(biāo)時,patch屬性則是Circle對象。例如下面的語句設(shè)置Axes對象的背景顏色為綠色:

      >>> fig = plt.figure()
      >>> ax = fig.add_subplot(111)
      >>> ax.patch.set_facecolor("green")
      

      當(dāng)你調(diào)用Axes的繪圖方法(例如plot),它將創(chuàng)建一組Line2D對象,并將所有的關(guān)鍵字參數(shù)傳遞給這些Line2D對象,并將它們添加進Axes.lines屬性中,最后返回所創(chuàng)建的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軸的數(shù)據(jù),一次繪制多條曲線。

      與plot方法類似,繪制直方圖的方法bar和繪制柱狀統(tǒng)計圖的方法hist將創(chuàng)建一個Patch對象的列表,每個元素實際上都是Patch的子類Rectangle,并且將所創(chuàng)建的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屬性進行操作,而是調(diào)用add_line或者add_patch等方法,這些方法幫助我們完成許多屬性設(shè)置工作:

      >>> 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() # 數(shù)據(jù)的范圍和rect的大小一致
      (1.0, 1.0, 5.0, 12.0)
      >>> ax.autoscale_view() # 自動調(diào)整坐標(biāo)軸范圍
      >>> ax.get_xlim() # 于是X軸可以完整顯示rect
      (1.0, 6.0)
      >>> plt.show()
      

      通過上面的例子我們可以看出,add_patch方法幫助我們設(shè)置了rect的axes和transform屬性。

      下面詳細(xì)列出Axes包含各種Artist對象的屬性:

      • artists : Artist對象列表
      • patch : 作為Axes背景的Patch對象,可以是Rectangle或者Circle
      • collections : Collection對象列表
      • images : AxesImage對象列表
      • legends : Legend對象列表
      • lines : Line2D對象列表
      • patches : Patch對象列表
      • texts : Text對象列表
      • xaxis : XAxis對象
      • yaxis : YAxis對象

      下面列出Axes的創(chuàng)建Artist對象的方法:

      Axes的方法 所創(chuàng)建的對象 添加進的列表
      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 # 返回的對象已經(jīng)添加進了collections列表中
      [<matplotlib.collections.CircleCollection object at 0x06004230>]
      >>> fig.show()
      >>> t.get_sizes() # 獲得Collection的點數(shù)
      20
      
      _images/pyplot_artist02.png

      圖5.5 用scatter函數(shù)繪制散列圖

      5.4.4 Axis容器

      Axis容器包括坐標(biāo)軸上的刻度線、刻度文本、坐標(biāo)網(wǎng)格以及坐標(biāo)軸標(biāo)題等內(nèi)容??潭劝ㄖ骺潭群透笨潭?,分別通過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() # 獲得刻度標(biāo)簽列表
      <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>
      

      獲得刻度線或者刻度標(biāo)簽之后,可以設(shè)置其各種屬性,下面設(shè)置刻度線為綠色粗線,文本為紅色并且旋轉(zhuǎn)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)
      

      最終的結(jié)果圖如下:

      _images/pyplot_axis01.png

      圖5.6 手工配置X軸的刻度線和刻度文本的樣式

      上面的例子中,獲得的副刻度線列表為空,這是因為用于計算副刻度的對象缺省為NullLocator,它不產(chǎn)生任何刻度線;而計算主刻度的對象為AutoLocator,它會根據(jù)當(dāng)前的縮放等配置自動計算刻度的位置:

      >>> axis.get_minor_locator() # 計算副刻度的對象
      <matplotlib.ticker.NullLocator instance at 0x0A014300>
      >>> axis.get_major_locator() # 計算主刻度的對象
      <matplotlib.ticker.AutoLocator instance at 0x09281B20>
      

      我們可以使用程序為Axis對象設(shè)置不同的Locator對象,用來手工設(shè)置刻度的位置;設(shè)置Formatter對象用來控制刻度文本的顯示。下面的程序設(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è)置兩個坐標(biāo)軸的范圍
      pl.ylim(-1.5,1.5)
      pl.xlim(0, np.max(x))
      
      # 設(shè)置圖的底邊距
      pl.subplots_adjust(bottom = 0.15)
      
      pl.grid() #開啟網(wǎng)格
      
      # 主刻度為pi/4
      ax.xaxis.set_major_locator( MultipleLocator(np.pi/4) )
      
      # 主刻度文本用pi_formatter函數(shù)計算
      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中定義,程序中使用到如下兩個類:

      • MultipleLocator : 以指定值的整數(shù)倍為刻度放置刻度線
      • FuncFormatter : 使用指定的函數(shù)計算刻度文本,他會傳遞給所指定的函數(shù)兩個參數(shù):刻度值和刻度序號,程序中通過比較笨的辦法計算出刻度值所對應(yīng)的刻度文本

      此外還有很多預(yù)定義的Locator和Formatter類,詳細(xì)內(nèi)容請參考相應(yīng)的API文檔。

      _images/pyplot_axis02.png

      圖5.7 手工配置X軸的刻度線的位置和文本,并開啟副刻度


        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約