matplotlib封裝探索

本文參考這裏,轉載請註明出處!繪圖:matplotlib核心剖析

matplotlib是基於Python的開源項目,旨在爲Python提供一個數據繪圖包。在建模過程中數據分佈,圖表的分析非常重要。

Matplotlib使用numpy數組運算,並調用一系列其他的Python庫來實現硬件交互。matplotlib的核心是一套由對象構成的繪圖API。

matplotlib項目由John D. Hunter發起,他於2012年由於癌症去世,默哀。

函數式構圖

matplotlib受MATLAB啓發構建,注意,MATLIB是面向過程的,matplotlib爲了方便用戶過度,有一套完全仿照MATLIB的函數形式的用戶結構,在matplotlib.pyplot中,就是我們經常在比賽中使用的如下引入方式import matplotlib.pyplot as plt

# hello world
import matplotlib.pyplot as plt
plt.plot([0,1], [0,1])
plt.title("plot hello world")
plt.xlabel("x value")
plt.ylabel("y value")
plt.savefig("demo.png")

demo

這種函數式調用非常方便,但是我們知道python中一切皆對象,函數式編程是通過封裝對象來實現的,將構建對象的過程中封裝在函數中 。matplotlib也是如此,所以本質上還是通過構建對象來構建圖像。常用的繪圖函數plot,scatter,pie,bar,contour,imshow

面向對象的編程

函數式編程對用戶很友好,也很便利,但是也有缺點:

  • 增加了一層調用,降低了效率
  • 隸屬關係被掩蓋,整個matplotlib包由一系列有組織有隸屬關係的對象構成,函數式編程掩蓋了這種關係。
  • 細節被掩蓋,pyplot不能完全覆蓋對象體系的所有功能
  • 每件事都可以有至少有兩種方式完成,用戶容易混淆。

對於開發者或者想更加熟練使用matplotlib還是瞭解對象纔好。

# 用面向對象的方法來實現以上程序
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

fig    = Figure()
canvas = FigureCanvas(fig)
ax     = fig.add_axes([0.1, 0.1, 0.8, 0.8])

line,  = ax.plot([0,1], [0,1])
ax.set_title("a straight line (OO)")
ax.set_xlabel("x value")
ax.set_ylabel("y value")

canvas.print_figure('demo.png')

demo_oo

理解對象

在matplotlib中,整個圖像爲一個Figure對象,在Figure對象中可以包含一個或者多個Axes對象,每個Axes對象都有一個擁有自己座標系統的繪圖區域。邏輯關係如下:

這裏寫圖片描述

看上邊的直線圖,整個圖像就是一個Figure對象,我們的繪圖只有一個座標系區域,此外還有以下對象。

這裏寫圖片描述

其中title爲標題,axis爲座標軸,label爲座標軸標註,tick爲刻度線,tick label爲刻度註釋,各個對象的關係如下所示。

這裏寫圖片描述

data是數據繪圖的關鍵部分,但是必須和xaxis,yaxis,title一起纔有意義,才能構成一個繪圖區域axes,title, tick label和label都是文本(Text),而tick是由短線(Line 2D)和tick label構成,xaxis由座標軸的線和tick以及label構成,ax由xaxis, yaxis, title, data構成,ax自身又構成了fig的一部分。上面的每個對象,無論是Line2D, Text還是fig,它們都來自於一個叫做Artist的基類。

OO繪圖源程序還有一個canvas對象,它代表了真正進行繪圖的後端,Artist只是程序邏輯上的繪圖,它必須連接後端繪圖程序才能真正在繪圖程序上繪製。可以將canvas理解爲繪圖的物理(硬件)實現。

座標

三種座標:

  • 顯示座標:計算機屏幕是以像素點構成,顯示座標就是以像素點爲單位,最貼近硬件的座標體系。缺點,不容易被納入繪圖邏輯,在不同的顯示器上需要調整像素值才能保證圖像不變形。
  • 圖像座標:將一張圖的左下角視爲原點,將圖像的x方向和y方向總長度都看做1,x方向的0.2就是指20%的圖像在x方向的總長,y方向0.8的長度指80%的y方向總長。(0.5, 0.5)是圖像的中點,(1, 1)指圖像的右上角。在上邊的OO繪圖代碼中,ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]),前兩個參數爲axes的左下角在fig上的位置,後兩個原始是axes在fig的圖像座標上x和y方向的長度,fig的圖像座標爲圖像座標(figure座標)。類似地,每個axes有屬於自己的圖像座標,稱爲數據座標(axes座標)
  • 數據座標:實際繪圖使用,繪製具體數據。

如果是具體數據,那麼數據座標系符合我們需求。如果是標題這樣的附加信息,axes座標符合我們需求。如果是整個圖像的註解,Figure座標系更符合需求。每一個Aritist對象都有一個transform屬性,如果爲顯示座標,transform爲None。

以更大自由度(更底層)來繪製圖形可以參見這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章