Figure對(duì)象全解析 專注于matplotlib的pyplot函數(shù)式繪圖的人,可能會(huì)說:Figure有什么需要解析的,我一直使用“plt.figure()”就足夠了,有時(shí)我甚至直接'plt.plot()'就行了。Figure對(duì)象有必要解析嗎? Figure對(duì)象是matplotlib繪圖的開始,它是連接后端的橋梁,它是繪圖元素定位、布局的基礎(chǔ)。 一切可見元素皆是Artistmpl框架的artist模塊中定義了一個(gè)抽象基類,用作定義下述對(duì)象的父類:
這些對(duì)象都是Artist的子類。 Artist提供了所有mpl繪圖的所有可見元素。Artist對(duì)象有兩種類型:
容器類型:可以容納、包含其它Artist對(duì)象的對(duì)象。如Figure, Axes。Figure可以包含多個(gè)Axes、Text等。Axes包含Axis,Line2D,Text等。 容器把包含在其內(nèi)的對(duì)象組織為一個(gè)整體。 簡(jiǎn)單類型:是標(biāo)準(zhǔn)的、最基本的繪圖元件,不能再包含其它對(duì)象,如Line2D, Text, Rectangle等。 Figure是一個(gè)頂級(jí)容器matplotlib.artist模塊提供了一個(gè) Figure 類,它是頂層的容器型Artist,它容納所有繪圖元件。 在2D平面坐標(biāo)中,你應(yīng)該把它看成一個(gè)矩形(Rectangle)區(qū)域。創(chuàng)建一個(gè)Figure也就是在畫布上定義一塊矩形區(qū)域。 這個(gè)矩形區(qū)域有兩個(gè)最根本的用處:
第2點(diǎn)非常重要,它是坐標(biāo)變換、其它對(duì)象尺寸設(shè)置的參考對(duì)象。 Figure默認(rèn)是白色、無邊框的,把它填充一個(gè)其它顏色的前景色并設(shè)置邊框有助于我們理解它。 輸入如下代碼,創(chuàng)建一個(gè)有前景色和邊框的Figure: from matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.figure import Figurefig =Figure(figsize=(6.4,4.8), dpi=100, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=10.0, frameon=True, )canvas = FigureCanvasAgg(fig)s, (width, height) = canvas.print_to_buffer() from PIL import Image #調(diào)用PILim = Image.frombytes('RGBA', (width, height), s)im.show() Figure坐標(biāo)系統(tǒng)Figure最重要的作用是提供了一個(gè)坐標(biāo)系統(tǒng)。如上圖所示,創(chuàng)建Figure時(shí),它就在畫布上繪制了一塊矩形區(qū)域。 該矩形定義了Figure坐標(biāo)系統(tǒng),矩形的左下角的坐標(biāo)是(0.0, 0.0),右上角坐標(biāo)是(1.0,1.0)。 當(dāng)我們要將一個(gè)簡(jiǎn)單的artist放到figure中時(shí),我們需要提供一個(gè)(x, y)坐標(biāo),x, y在[0.0, 1.0]之間,用于確定放置的位置。 from matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.figure import Figurefig =Figure(figsize=(6.4,4.8), dpi=100, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=10.0, frameon=True, )canvas = FigureCanvasAgg(fig)#在figure的中心添加一個(gè)文本fig.text(0.5,0.5,'fig_center') s, (width, height) = canvas.print_to_buffer() from PIL import Image im = Image.frombytes('RGBA', (width, height), s)im.show() 如果要將一個(gè)容器類的artist添加到figure中時(shí),如,我們添加一個(gè)Axes到Figure中,我們不僅要提供定位坐標(biāo)(axes的左下角在figure中的位置),還要指定子容器相對(duì)于Figure的大小,用分?jǐn)?shù)表示,即把Figure的寬和長(zhǎng)看為1,子容器是它的“0.?”。 from matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.figure import Figurefrom matplotlib.axes import Axesfig =Figure(figsize=(6.4,4.8), dpi=100, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=10.0, frameon=True, )canvas = FigureCanvasAgg(fig)fig.text(0.5,0.5,'fig_center')#請(qǐng)注意下面的axes定義ax = Axes(fig,[0.1,0.2,0.3,0.8])fig.add_axes(ax)s, (width, height) = canvas.print_to_buffer() from PIL import Image #調(diào)用PILim = Image.frombytes('RGBA', (width, height), s)im.show() 請(qǐng)將這張圖刻在腦中 添加到figure中的axes,axes的左下角是定位坐標(biāo),寬度和高度定義了axes的尺寸。axes的定位坐標(biāo)和尺寸都是相對(duì)于figue來計(jì)算的。 理解Figure的坐標(biāo)定位、尺寸參照作用,比掌握Figure的眾多參數(shù)設(shè)置更重要! 簡(jiǎn)單地理解后端因?yàn)镕igure中一些參數(shù)、方法與后端有關(guān),而我們一般繪圖又很少需要與后端打交道,但如果后端一點(diǎn)都不了解,又不利于從整體上把握matplotlib的架構(gòu),所以這里用草根的語言和理解簡(jiǎn)單地介紹一下后端,記住以下幾點(diǎn)就差不多了,中高級(jí)部分再詳細(xì)討論。
試想,你并沒有直接操控計(jì)算機(jī)顯示系統(tǒng),你僅是在寫python代碼,你的代碼是如何與計(jì)算機(jī)顯示系統(tǒng)良好對(duì)接的呢?你繪制的繪圖元件為什么總是能正確地在屏幕上顯示出來,而沒有發(fā)生位置錯(cuò)亂、顏色錯(cuò)誤呢? 簡(jiǎn)單地理解:后端就是將你的代碼轉(zhuǎn)換為計(jì)算機(jī)圖形語言,并正確地在屏幕上顯示出來的后臺(tái)程序塊。 Figure基礎(chǔ)參數(shù)使用Figure類的調(diào)用 class matplotlib.figure.Figure( figsize=None, dpi=None, facecolor=None, edgecolor=None, linewidth=0.0, frameon=None, subplotpars=None, tight_layout=None, constrained_layout=None) 實(shí)例化Figure類時(shí),需要9個(gè)參數(shù),但Figure類定義中,這些形參都提供了默認(rèn)值。所以,我們可以一個(gè)參數(shù)都不提供,就會(huì)取默認(rèn)參數(shù)rcParams中的設(shè)置創(chuàng)建一個(gè)figure實(shí)例。 前往“Python草堂”群下載該表 大部分參數(shù)的設(shè)置和用法一目了然,下面補(bǔ)充解釋下面幾個(gè)參數(shù):
color:matplotlib的顏色,可以使用常用顏色的名稱指定顏色,如'red', 'blue'等,也可以使用浮點(diǎn)數(shù)3元素元組表示的RGB顏色,如(0.1, 0.2, 0.5),也可以這樣(239/256,239/256,239/256)。 subplotpars:是SubplotParams類的一個(gè)實(shí)例,定義子圖參數(shù)。如果不提供該參數(shù),則用rcParams['figure.subplot.*']作為子圖參數(shù)。一般無需設(shè)置它,默認(rèn)即可。 class matplotlib.figure.SubplotParams( left=None, bottom=None, right=None, top=None, wspace=None, hspace=None ) 要自定義Figure的subplotpars參數(shù),先創(chuàng)建一個(gè)figure.SubplotParams類的實(shí)例。該類的前4個(gè)參數(shù)依次是子圖(矩形區(qū)域)的“左、底、右、頂”邊在Figure中的位置,浮點(diǎn)數(shù)。 *wspace: * float,子圖之間預(yù)留空間的寬度大小,用平均axis軸線寬度的分?jǐn)?shù)表示。 *hspace: * float,子圖之間預(yù)留空間的高度大小,用平均axis軸線高度的分?jǐn)?shù)表示。 下面是默認(rèn)的rcParams['figure.subplot.*'],單位是figure的分?jǐn)?shù)。 'figure.subplot.bottom': 0.11, 'figure.subplot.hspace': 0.2, 'figure.subplot.left': 0.125, 'figure.subplot.right': 0.9, 'figure.subplot.top': 0.88, 'figure.subplot.wspace': 0.2, tight_layout:布爾值,或字典。設(shè)置如何調(diào)整子圖的布局。如果為False,使用subplotpars參數(shù);如果為True,使用帶有默認(rèn)padding的tight_layout調(diào)整subplot參數(shù)。 tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None, rect=None)
下圖是設(shè)置:tight_layout = False /True 的效果比較。 from matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.figure import Figure,SubplotParamsfrom matplotlib.axes import Axesimport numpy as npfrom numpy import mathfig =Figure(figsize=(9.6,4.8), dpi=100, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=10.0, frameon=True, subplotpars=None, tight_layout=True, constrained_layout=None )canvas = FigureCanvasAgg(fig)ax_fca = (249/256,244/256,206/256)ax_fcb = (138/256,176/256,209/256)pl_cb = (8/256,89/256,156/256)pl_cr = (239/256,8/256,8/256)ax_a = fig.add_subplot(121,facecolor=ax_fca)ax_b = fig.add_subplot(122,facecolor=ax_fcb) x = np.arange(0, 2*math.pi, 0.001)y = np.sin(x)ax_a.plot(x, y, color=pl_cr)ax_b.plot(x, y, color=pl_cb) ax_a.plot(x, np.cos(x), color='g')ax_b.plot(x, np.cos(x), color='r') s, (width, height) = canvas.print_to_buffer() from PIL import Image im = Image.frombytes('RGBA', (width, height), s)im.show() tight_layout=True tight_layout=False 還可以提供一個(gè)字典給 tight_layout,下面是在字典中設(shè)置tight_layout的示例: from matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.figure import Figure,SubplotParamsfrom matplotlib.axes import Axesimport numpy as npfrom numpy import mathtl = {'pad':2.0,'h_pad':1.0,'w_pad':5.0,'rect':(0.1,0.1,0.9,0.9)}fig =Figure(figsize=(9.6,4.8), dpi=100, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=10.0, frameon=True, subplotpars=None, tight_layout=tl, constrained_layout=False )canvas = FigureCanvasAgg(fig)ax_fca = (249/256,244/256,206/256)ax_fcb = (138/256,176/256,209/256)pl_cb = (8/256,89/256,156/256)pl_cr = (239/256,8/256,8/256)ax_a = fig.add_subplot(121,facecolor=ax_fca)ax_b = fig.add_subplot(122,facecolor=ax_fcb) x = np.arange(0, 2*math.pi, 0.001)y = np.sin(x)ax_a.plot(x, y, color=pl_cr)ax_b.plot(x, y, color=pl_cb) ax_a.plot(x, np.cos(x), color='g')ax_b.plot(x, np.cos(x), color='r') s, (width, height) = canvas.print_to_buffer() from PIL import Image im = Image.frombytes('RGBA', (width, height), s)im.show() 為 有意將tight_layout的一些參數(shù)設(shè)置得很夸張,以突出效果: 請(qǐng)與上面的圖比較 constrained_layout:布爾值,如果'True',使用約束布局來調(diào)整繪圖元素的位置。類似 tight_layout, 但設(shè)計(jì)得更加靈活。中級(jí)篇中再詳細(xì)介紹。 注意:constrained_layout=True 與 subplots_adjust 和 tight_layout 不兼容,即不能同時(shí)設(shè)置為True。 下一篇將詳細(xì)討論figure的方法和屬性。 |
|