[053]matplotlib繪圖基礎

轉載自:http://blog.csdn.net/pipisorry/article/details/37742423

matplotlib介紹

        matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地進行製圖。而且也可以方便地將它作爲繪圖控件,嵌入GUI應用程序中。它的文檔相當完備,並且Gallery頁面 中有上百幅縮略圖,打開之後都有源程序。因此如果你需要繪製某種類型的圖,只需要在這個頁面中瀏覽/複製/粘貼一下,基本上都能搞定。
        在Linux下比較著名的數據圖工具還有gnuplot,這個是免費的,Python有一個包可以調用gnuplot,但是語法比較不習慣,而且畫圖質量不高。而Matplotlib則比較強:Matlab的語法、python語言、latex的畫圖質量(還可以使用內嵌的latex引擎繪製的數學公式)。

    可以在Ipython中輸入類似"plt.plot??"的命令查看pyplot模塊的函數是如何對各種繪圖對象進行包裝的。

面向對象方式繪圖

matplotlib實際上是一套面向對象的繪圖庫,它所繪製的圖表中的每個繪圖元素,例如線條Line2D、文字Text、刻度等在內存中都有一個對象與之對應。

爲了方便快速繪圖matplotlib通過pyplot模塊提供了一套和MATLAB類似的繪圖API,將衆多繪圖對象所構成的複雜結構隱藏在這套API內部。我們只需要調用pyplot模塊所提供的函數就可以實現快速繪圖以及設置圖表的各種細節。pyplot模塊雖然用法簡單,但不適合在較大的應用程序中使用

獲取當前圖和軸線

爲了將面向對象的繪圖庫包裝成只使用函數的調用接口,pyplot模塊的內部保存了當前圖表以及當前子圖等信息。當前的圖表和子圖可以使用plt.gcf()和plt.gca()獲得,分別表示"Get Current Figure"和"Get Current Axes"。在pyplot模塊中,許多函數都是對當前的Figure或Axes對象進行處理,比如說:    plt.plot()實際上會通過plt.gca()獲得當前的Axes對象ax,然後再調用ax.plot()方法實現真正的繪圖。

如,用下面的代碼先獲得axes對象再用ax來操作

ax = plt.gca()
ax = plt.axes()

地如設置xy軸的tickers就要用ax.yaxis來操作

ax.yaxis.set_minor_locator(yminorLocator)

安裝numpy和matplotlib

pip install numpy

pip install matplotlib

matplotlib安裝出錯

ImportError: libBLT.2.4.so.8.6: cannot open shared object file: No such file or directory, please install the python3-tk package

[import matplotlib.pyplot as plt fails with error about python-tk]

檢測是否安裝成功:

>>> import numpy
>>> numpy.__version__

>>> import matplotlib
>>> matplotlib.__version__

不同繪圖語言比較

工科生說Matlab完爆其他
數學系的說Mathematica高貴冷豔
統計系的說R語言作圖領域天下無敵 
計算機系的說Python低調奢華有內涵
[如何在論文中畫出漂亮的插圖]


matplotlib.pyplot模塊 - 快速繪圖

matplotlib的pyplot子庫提供了和matlab類似的繪圖API,方便用戶快速繪製2D圖表。

1.調用figure創建一個繪圖對象,並且使它成爲當前的繪圖對象。(可選)

plt.figure(figsize=(8,4))
也可以不創建繪圖對象直接調用接下來的plot函數直接繪圖,matplotlib會爲我們自動創建一個繪圖對象!!
如果需要同時繪製多幅圖表的話,可以是給figure傳遞一個整數參數指定圖標的序號,如果所指定序號的繪圖對象已經存在的話,將不創建新的對象,而只是讓它成爲當前繪圖對象。
figsize參數:指定繪圖對象的寬度和高度,單位爲英寸;dpi參數指定繪圖對象的分辨率,即每英寸多少個像素,缺省值爲80。因此本例中所創建的圖表窗口的寬度爲8*80 = 640像素。
但是用show()出來的工具欄中的保存按鈕保存下來的png圖像的大小是800*400像素。這是因爲保存圖表用的函數savefig使用不同的DPI配置,savefig函數也有一個dpi參數,如果不設置的話,將使用matplotlib配置文件中的配置,此配置可以通過如下語句進行查看:>>>matplotlib.rcParams["savefig.dpi"]100

2.通過調用plot函數在當前的繪圖對象中進行繪圖

    plt.plot(years, price, 'b*')#,label="$cos(x^2)$")
    plt.plot(years, price, 'r')
Note:
1. 第一句將x,y數組傳遞給plot
2.通過第三個參數"b--"指定曲線的顏色和線型,這個參數稱爲格式化參數,它能夠通過一些易記的符號快速指定曲線的樣式。其中b表示藍色,"--"表示線型爲虛線。
3. 用關鍵字參數指定各種屬性:label : 給所繪製的曲線一個名字,此名字在圖示/圖例(legend)中顯示。只要在字符串前後添加"$"符號,matplotlib就會使用其內嵌的latex引擎繪製的數學公式。color : 指定曲線的顏色linewidth : 指定曲線的寬度
具體參見【附錄 - matplotlib中的作圖參數】

3.設置繪圖對象的各個屬性

    plt.xlabel("years(+2000)")   #設置X軸的文字
    plt.ylabel("housing average price(*2000 yuan)")
    plt.ylim(0, 15)    #設置Y軸的範圍
    plt.title('line_regression & gradient decrease')    #設置圖表的標題
    plt.legend()    #顯示圖示

設置xlabel和ylabel顯示的大小

import matplotlib
matplotlib.rc('xtick', labelsize=18)
matplotlib.rc('ytick', labelsize=18)

給一些特殊點做註釋

我們希望在 2π/3的位置給兩條函數曲線加上一個註釋。首先,我們在對應的函數圖像位置上畫一個點;然後,向橫軸引一條垂線,以虛線標記;最後,寫上標籤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...

t = 2*np.pi/3
plot([t,t],[0,np.cos(t)], color ='blue', linewidth=2.5, linestyle="--")
scatter([t,],[np.cos(t),], 50, color ='blue')

annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
         xy=(t, np.sin(t)), xycoords='data',
         xytext=(+10, +30), textcoords='offset points', fontsize=16,
         arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

plot([t,t],[0,np.sin(t)], color ='red', linewidth=2.5, linestyle="--")
scatter([t,],[np.sin(t),], 50, color ='red')

annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
         xy=(t, np.cos(t)), xycoords='data',
         xytext=(-90, -50), textcoords='offset points', fontsize=16,
         arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
...

點擊圖片下載相應 Python 代碼

精益求精

座標軸上的記號標籤被曲線擋住了,作爲強迫症患者(霧)這是不能忍的。我們可以把它們放大,然後添加一個白色的半透明底色。這樣可以保證標籤和曲線同時可見。

1
2
3
4
5
...
for label in ax.get_xticklabels() + ax.get_yticklabels():
    label.set_fontsize(16)
    label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65 ))
...

點擊圖片下載相應 Python 代碼

[Matplotlib 教程*]

plt.text(0.5,0.8,'subplot words',color='blue',ha='center',transform=ax.trans    Axes)  

plt.figtext(0.1,0.92,'figure words',color='green')  

plt.annotate('buttom',xy=(0,0),xytext=(0.2,0.2),arrowprops=dict(facecolor='blue', shrink=0.05))  


[matplotlib繪圖,圖標註釋(2) ]

4.最後調用plt.show()顯示出我們創建的所有繪圖對象。

Matplotlib 裏的常用類的包含關係爲 Figure -> Axes -> (Line2D, Text, etc.)一個Figure對象可以包含多個子圖(Axes),在matplotlib中用Axes對象表示一個繪圖區域,可以理解爲子圖。

matplotlib繪圖顯示同時繼續跑下面的代碼

方式1:block=False參數或者plt.show(0)

from matplotlib.pyplot import plot, draw, show
def p():
    plot([1, 2, 3])
    show(block=False)
p()
print('continue computation')
input()
但是在外部應該加一個input()輸入enter結束圖形顯示,否則鼠標點擊是關閉不了圖形的。

方式2:draw()

from matplotlib.pyplot import plot, draw, show
def p():
    plot([1, 2, 3])
    draw()
p()
print('continue computation')
# at the end call show to ensure window won't close.
show()
唯一的缺點就是,show()函數放在了繪圖函數外了。

方式3:使用多線程

from multiprocessing import Process
from matplotlib import pyplot as plt
def p(args):
    plt.plot([1, 2, 3])
    plt.show()
p = Process(target=p, args=([1, 2, 3],))
p.start()

print('continue computation')

p.join()

唯一的缺點就是要寫多線程的代碼,但是至少plot模塊都在一個函數中。

Note: target應爲函數名而不應該是函數調用,否則還是會繪圖阻止程序向下運行。

[Is there a way to detach matplotlib plots so that the computation can continue?]

清空plt繪製的內容

plt.cla()

plt.close(0)# 關閉圖 0

plt.close('all') 關閉所有圖

圖形保存和輸出設置

可以調用plt.savefig()將當前的Figure對象保存成圖像文件,圖像格式由圖像文件的擴展名決定。下面的程序將當前的圖表保存爲“test.png”,並且通過dpi參數指定圖像的分辨率爲 120,因此輸出圖像的寬度爲“8X120 = 960”個像素。
plt.savefig("test.png",dpi=120)
也可以通過show()出來的圖形界面手動保存和設置
matplotlib中繪製完成圖形之後通過show()展示出來,我們還可以通過圖形界面中的工具欄對其進行設置和保存
matplotlib修改圖片大小:圖形界面下方工具欄可以設置圖形上下左右的邊距
如果想在跑程序外部查看圖片,可以這樣:

plt.savefig('/tmp/1.png')
subprocess.run('xdg-open /tmp/1.png', shell=True)
有個問題就是繪製的圖中橫縱座標下面的+3.156e1代表什麼意思?也不是座標值的單位,那是什麼呢。。。

5. 繪製多子圖
可以使用subplot()快速繪製包含多個子圖的圖表,它的調用形式如下:
subplot(numRows, numCols, plotNum)

matplotlib.pyplot.subplots(nrows=1ncols=1sharex=Falsesharey=Falsesqueeze=Truesubplot_kw=Nonegridspec_kw=None**fig_kw)

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

通過axisbg參數給每個軸設置不同的背景顏色。

image

subplot()返回它所創建的Axes對象,我們可以將它用變量保存起來,然後用sca()交替讓它們成爲當前Axes對象,並調用plot()在其中繪圖。

調節軸之間的間距和軸與邊框之間的距離

當繪圖對象中有多個軸的時候,可以通過工具欄中的Configure Subplots按鈕,交互式地調節軸之間的間距和軸與邊框之間的距離。

如果希望在程序中調節的話,可以調用subplots_adjust函數,它有left, right, bottom, top, wspace, hspace等幾個關鍵字參數,這些參數的值都是0到1之間的小數,它們是以繪圖區域的寬高爲1進行正規化之後的座標或者長度。

[matplotlib.pyplot.subplots_adjust]

[matplotlib.pyplot.subplots]

6.繪製多圖表

如果需要同時繪製多幅圖表,可以給figure()傳遞一個整數參數指定Figure對象的序號,如果序號所指定的Figure對象已經存在,將不創建新的對象,而只是讓它成爲當前的Figure對象。

[python] view plain copy
  1. import numpy as np  
  2. import matplotlib.pyplot as plt   
  3.   
  4. plt.figure(1# 創建圖表1  
  5. plt.figure(2# 創建圖表2  
  6. ax1 = plt.subplot(211# 在圖表2中創建子圖1  
  7. ax2 = plt.subplot(212# 在圖表2中創建子圖2  
  8.    
  9. x = np.linspace(03100)  
  10. for i in xrange(5):  
  11.     plt.figure(1)  #選擇圖表1  
  12.     plt.plot(x, np.exp(i*x/3))  
  13.     plt.sca(ax1)   #選擇圖表2的子圖1  
  14.     plt.plot(x, np.sin(i*x))  
  15.     plt.sca(ax2)  # 選擇圖表2的子圖2  
  16.     plt.plot(x, np.cos(i*x))  
  17. plt.show()  
/tech/static/books/scipy/_images/matplotlib_multi_figure.png

7. 在圖表中顯示中文

matplotlib的缺省配置文件中所使用的字體無法正確顯示中文。爲了讓圖表能正確顯示中文,可以有幾種解決方案。

  1. 在程序中直接指定字體。
  2. 在程序開頭修改配置字典rcParams。
  3. 修改配置文件。

比較簡便的方式是,中文字符串用unicode格式,例如:u''測試中文顯示'',代碼文件編碼使用utf-8 加上" # coding = utf-8  "一行。

[matplotlib輸出圖象的中文顯示問題]

8. 面向對象畫圖

matplotlib API包含有三層,Artist層處理所有的高層結構,例如處理圖表、文字和曲線等的繪製和佈局。通常我們只和Artist打交道,而不需要關心底層的繪製細節。

直接使用Artists創建圖表的標準流程如下:

  • 創建Figure對象
  • 用Figure對象創建一個或者多個Axes或者Subplot對象
  • 調用Axies等對象的方法創建各種簡單類型的Artists
[python] view plain copy
  1. import matplotlib.pyplot as plt  
  2. X1 = range(050)  
  3. Y1 = [num**2 for num in X1] # y = x^2 X2 = [0, 1] Y2 = [0, 1] # y = x  
  4.   
  5. Fig = plt.figure(figsize=(8,4)) # Create a `figure' instance  
  6. Ax = Fig.add_subplot(111# Create a `axes' instance in the figure  
  7. Ax.plot(X1, Y1, X2, Y2) # Create a Line2D instance in the axes  
  8.   
  9. Fig.show()   
  10. Fig.savefig("test.pdf")  
[matplotlib-繪製精美的圖表]

[什麼是 Matplotlib (面向對象繪圖)]

[Python圖表繪製:matplotlib繪圖庫入門]
皮皮blog



Matplotlib中的作圖參數

a set of tables that show main properties and styles
在IPython中輸入 "plt.plot?" 可以查看格式化字符串的詳細配置。

線屬性Line properties

Property Description Appearance
alpha (or a) alpha transparency on 0-1 scale figures/alpha.png
antialiased True or False - use antialised rendering figures/aliased.pngfigures/antialiased.png
color (or c) matplotlib color arg figures/color.png
linestyle (or ls) see Line properties  
linewidth (or lw) float, the line width in points figures/linewidth.png
solid_capstyle Cap style for solid lines figures/solid_capstyle.png
solid_joinstyle Join style for solid lines figures/solid_joinstyle.png
dash_capstyle Cap style for dashes figures/dash_capstyle.png
dash_joinstyle Join style for dashes figures/dash_joinstyle.png
marker see Markers  
markeredgewidth (mew) line width around the marker symbol figures/mew.png
markeredgecolor (mec) edge color if a marker is used figures/mec.png
markerfacecolor (mfc) face color if a marker is used figures/mfc.png
markersize (ms) size of the marker in points figures/ms.png

顏色(color 簡寫爲 c):

    藍色: 'b' (blue)
    綠色: 'g' (green)
    紅色: 'r' (red)
    藍綠色(墨綠色): 'c' (cyan)
    紅紫色(洋紅): 'm' (magenta)
    黃色: 'y' (yellow)
    黑色: 'k' (black)
    白色: 'w' (white)
    灰度表示: e.g. 0.75 ([0,1]內任意浮點數)
    RGB表示法: e.g. '#2F4F4F' 或 (0.18, 0.31, 0.31)
    任意合法的html中的顏色表示: e.g. 'red', 'darkslategray'

遍歷使用顏色:colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))

[Colormaps]

線型Line styles(簡寫爲 ls):

  • 實線: '-'
  • 虛線: '--'
  • 虛點線: '-.'
  • 點線: ':'
  • 點: '.'
Note: 後面的都是設置點型,感覺有多餘的設計。
Symbol Description Appearance
- solid line figures/linestyle--.png
-- dashed line figures/linestyle---.png
-. dash-dot line figures/linestyle--dot.png
: dotted line figures/linestyle-:.png
. points figures/linestyle-dot.png
, pixels figures/linestyle-,.png
o circle figures/linestyle-o.png
^ triangle up figures/linestyle-^.png
v triangle down figures/linestyle-v.png
< triangle left figures/linestyle-<.png
> triangle right figures/linestyle->.png
s square figures/linestyle-s.png
+ plus figures/linestyle-+.png
x cross figures/linestyle-x.png
D diamond figures/linestyle-dd.png
d thin diamond figures/linestyle-d.png
1 tripod down figures/linestyle-1.png
2 tripod up figures/linestyle-2.png
3 tripod left figures/linestyle-3.png
4 tripod right figures/linestyle-4.png
h hexagon figures/linestyle-h.png
H rotated hexagon figures/linestyle-hh.png
p pentagon figures/linestyle-p.png
| vertical line figures/linestyle-|.png
_ horizontal line figures/linestyle-_.png

點型Markers(標記):

標記大小(markersize 簡寫爲 ms):    markersize: 實數
標記邊緣寬度(markeredgewidth 簡寫爲 mew):    markeredgewidth:實數
標記邊緣顏色(markeredgecolor 簡寫爲 mec):    markeredgecolor:顏色選項中的任意值
標記表面顏色(markerfacecolor 簡寫爲 mfc):    markerfacecolor:顏色選項中的任意值。   marker填充色
透明度(alpha):    alpha: [0,1]之間的浮點數
線寬(linewidth):    linewidth: 實數

設置marker顯示的個數(marker數目太多時可以使用): markevery. You could decide on the x locations where you want the marks, use e.g. numpy.searchsorted to find which data points the locations fall between, and then interpolate between the neighboring points to find the y coordinates. [Plot with fewer markers than data points (or a better way to plot CDFs?)]

Note: 可以通過設置mfc='none', mec='r'使plot繪製空心園。

markers標記

Symbol Description Appearance
0 tick left figures/marker-i0.png
1 tick right figures/marker-i1.png
2 tick up figures/marker-i2.png
3 tick down figures/marker-i3.png
4 caret left figures/marker-i4.png
5 caret right figures/marker-i5.png
6 caret up figures/marker-i6.png
7 caret down figures/marker-i7.png
o circle figures/marker-o.png
D diamond figures/marker-dd.png
h hexagon 1 figures/marker-h.png
H hexagon 2 figures/marker-hh.png
_ horizontal line figures/marker-_.png
1 tripod down figures/marker-1.png
2 tripod up figures/marker-2.png
3 tripod left figures/marker-3.png
4 tripod right figures/marker-4.png
8 octagon figures/marker-8.png
p pentagon figures/marker-p.png
^ triangle up figures/marker-^.png
v triangle down figures/marker-v.png
< triangle left figures/marker-<.png
> triangle right figures/marker->.png
d thin diamond figures/marker-d.png
, pixel figures/marker-,.png
+ plus figures/marker-+.png
. point figures/marker-dot.png
s square figures/marker-s.png
* star figures/marker-*.png
| vertical line figures/marker-|.png
x cross figures/marker-x.png
r'$\sqrt{2}$' any latex expression figures/marker-latex.png

[Quick references]

[matplotlib中的作圖參數]



座標軸設定

Axis容器包括座標軸的刻度線、刻度標籤、座標網格以及座標軸標題等內容。刻度包括主刻度和副刻度,分別通過get_major_ticks()和get_minor_ticks()方法獲得。每個刻度線都是一 個XTick或YTick對象,它包括實際的刻度線和刻度標籤。Axis 對象提供了 get_ticklabels()和get_ticklines()方法,可以直接獲得刻度標籤和刻度線。
>>> plt.plot([1,2,3],[4,5,6])
>>>plt.show()
>>> axis = plt.gca().xaxis
>>> axis.get_ticklocs()#獲得axis對象的刻度位置列表
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‘] 
獲得X軸上表示主刻度線的列表,可看到X軸上共有10條刻度線:
>>>  axis.get_ticklines()
<a list of 10 Line2D ticklines objects>
由於沒有副刻度線,因此副刻度線列表的長度爲0:
>>> axis.get_ticklines(minor=True) # 獲得副刻度線列表
<a list of 0 Line2D ticklines objects>
使用pyplot模塊中的xticks()能夠完成X軸上刻度標籤的配置:
>>>plt.xticks(fontsize=16, color="red", rotation=45)


Matplotlib中顯示負號問題


 matplotlib.rcParams['axes.unicode_minus']=False



MatPlotLib中設置座標軸主刻度標籤和次刻度標籤顯示

{配置刻度線位置Locator類-控制刻度標籤顯示Formatter類}

用於計算副刻度位置的對象默認爲 NullLocator,它不產生任何刻度線。而計算主刻度位置的對象爲AutoLocator,它會根據當前的縮放等配置自動計算刻度的位置。
matplotlib提供了多種配置刻度線位置的Locator類,以及控制刻度標籤顯示的Formatter 類。

與刻度定位和文本格式化相關的類都在matplotlib.ticker模塊中定義,載入了兩個類:MultipleLocaton, FuncFormatter可以以指定值的整數倍爲刻度放置主、副刻度線。
使用指定的函數計算刻度文本,它會將刻度值和刻度的序號作爲參數傳遞給計算刻度文本的函數。

對於次刻度顯示,如果要使用默認設置只要matplotlib.pyplot.minorticks_on()  

設置刻度示例

示例1

from matplotlib import ticker, pyplot as plt
... ...
ax = plt.gca()
ax.yaxis.set_minor_locator(ticker.MultipleLocator(.5)) # 將此y軸次刻度標籤設置爲0.5的倍數
ax.yaxis.set_minor_formatter(ticker.FormatStrFormatter('%1.1f')) # 設置y軸次標籤文本格式
ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%1.1f')) # 設置y軸主標籤文本的格式
ax.xaxis.grid(True, which='major') # x座標軸的網格使用主刻度
ax.yaxis.grid(True, which='minor') # y座標軸的網格使用次刻度

上面的示例中,實際主刻度標籤和副刻度標籤文本是重疊的,如果格式不一樣就會顯示不好,這樣可能需要下面的FuncFormatter。

示例2

下面的程序設置X軸的主刻度爲π/4,副刻度爲π/20,並且主刻度上的標籤用數學符號顯示π。
from matplotlib.ticker import MultipleLocator, FuncFormatter
ax.xaxis.set_major_locator( MultipleLocator(np.pi/4) ) 
ax.xaxis.set_minor_locator( MultipleLocator(np.pi/20) )
ax.xaxis.set_major_formatter( FuncFormatter( pi_formatter ) ) 
def pi_formatter(x, pos): 
    m = np.round(x / (np.pi/4))
    n = 4
    while m!=0 and 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)

ps:

選擇是否顯示刻度值:x軸上,1爲下,2爲上;y軸上,1爲左,2爲右;
for tick in ax.xaxis.get_major_ticks():
    tick.label1On = True
    tick.label2On = False
for tick in ax.yaxis.get_major_ticks():
    tick.label1On = False
    tick.label2On = False

選擇如何顯示刻度
ax.xaxis.set_ticks_position(‘none’)
ax.yaxis.set_ticks_position(‘right’)

完全自定義座標軸刻度及刻度值
ax.set_xticks([-250, -200, -150, -100, -50, 0, 50, 100, 150, 200])
ax.set_xticklabels([‘-250’, ”, ‘-150’, ”, ‘-50′, ”, ’50’, ”, ‘150’, ”])
ax.set_yticks([-40, -20, 0, 20, 40, 60, 80])
ax.set_yticklabels([”, ”, ”, ”, ”, ”, ”])

分別設置x軸和y軸上刻度值的字體大小
for tick in ax.xaxis.get_major_ticks():
    tick.label1.set_fontsize(18)
for tick in ax.yaxis.get_major_ticks():
    tick.label1.set_fontsize(18)

這也可以設置刻度值字體大小
matplotlib.rc(‘xtick’, labelsize=20)
matplotlib.rc(‘ytick’, labelsize=20)

皮皮blog



配置屬性

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)
... ...

Note:getp函數只能對一個對象進行操作,它有兩種用法:

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

獲取當前的繪圖對象plt.gcf()

matplotlib的整個圖表爲一個Figure對象,此對象在調用plt.figure函數時返回,我們也可以通過plt.gcf函數獲取當前的繪圖對象

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

Figure對象axes屬性plt.gca()

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

用plt.getp可以發現AxesSubplot對象有很多屬性,例如它的lines屬性爲此子圖所包括的 Line2D 對象列表:

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

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


配置文件

繪製一幅圖需要對許多對象的屬性進行配置,例如顏色、字體、線型等等。我們在繪圖時,並沒有逐一對這些屬性進行配置,許多都直接採用了matplotlib的缺省配置。
matplotlib將這些缺省配置保存在一個名爲“matplotlibrc”的配置文件中,通過修改配置文件,我們可以修改圖表的缺省樣式。

在matplotlib中可以使用多個“matplotlibrc”配置文件,它們的搜索順序如下,順序靠前的配置文件將會被優先採用。

  • 當前路徑:程序的當前路徑。
  • 用戶配置路徑:通常在用戶文件夾的“.matplotlib”目錄下,可以通過環境變量MATPLOTLIBRC修改它的位置。
  • 系統配置路徑:保存在matplotlib的安裝目錄下的mpl-data中。

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

>>> import matplotlib
>>> matplotlib.get_configdir()
'C:\\Documents and Settings\\用戶名\\.matplotlib'

通過下面的語句可以獲得目前使用的配置文件的路徑:

>>> import matplotlib
>>> matplotlib.matplotlib_fname()
'C:\\Python26\\lib\\site-packages\\matplotlib\\mpl-data\\matplotlibrc'

由於在當前路徑和用戶配置路徑中都沒有找到配置文件,因此最後使用的是系統配置路徑下的配置文件。如果讀者將matplotlibrc複製一份到腳本的當前目錄(例如,c:\zhang\doc)下:

>>> 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"
>>> plt.plot([1,2,3,2])
>>> plt.show()

爲了方便對配置字典進行設置,可以使用rc()。下面的例子同時配置點標識符、線寬和顏色:

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

如果希望恢復到缺省的配置(matplotlib載入時從配置文件讀入的配置),可以調用rcdefaults()。

>>> matplotlib.rcdefaults()

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

>>> matplotlib.rcParams.update( matplotlib.rc_params() )
通過pyplot模塊也可以使用rcParams、rc和rcdefaults。
皮皮blog



圖像載入和顯示

imread()和imshow()提供了簡單的圖像載入和顯示功能.

plt.imread()

從圖像文件讀入數據,得到一個表示圖像的NumPy數組。它的第一個參數是文件名或文件對象,format參數指定圖像類型,如果省略,就由文件的擴展名決定圖像類型。 
對於灰度圖像,它返回一個形狀爲(M,N)的數組;對於彩色圖像,返冋形狀爲(M,N,C)的數組。 其中,M爲圖像的高度,N爲圖像的寬度,C爲3或4,表示圖像的通道數。
程序從“lena.jpg” 中讀入圖像數據:
>>>img = plt.imread(“lena.jpg")
>>> img.shape 
>>> (393, 512, 3)
>>> img.dtype
dtype(’uint8’)

plt.imshow

Display an image on the axes.
    matplotlib.pyplot.imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, hold=None, data=None, **kwargs)
X : array_like, shape (n, m) or (n, m, 3) or (n, m, 4)
vmin, vmax : scalar, optional, default: None
    vmin and vmax are used in conjunction with norm to normalize luminance data. Note if you pass a norm instance, your settings for vmin and vmax will be ignored.

>>> plt.imshow(img〉#注意圖像是上下顛倒的

#plt.imshow(img[::-1]) #反轉圖像數組的第0軸,不好理解?
>>> plt.imshow(img, origin=”lower”) # 讓圖表的原點在左下角
得到的數組img是一個形狀爲(393,512,3)的單字節無符號整數數組。這是因爲通常使用的圖像都是採用單字節分別保存每個像素的紅、綠、藍三個通道的分量。
注意,從JPG圖像中讀入的數據是上下顛倒的,爲了正常顯示圖像,可以將數組的第0軸反轉,或者設置imshow()的origin參數爲“lower”,從而讓所顯示圖表的原點在左下角。

如果三維數組的元素類型爲浮點數,那麼元素的取值範圍爲0.0到1.0,與顏色值0到255 對應,超出這個範圍可能會出現顏色異常的像素。
>>> img = img[: :-1]
>>> plt.imshow(img*1.0) #取值範圍爲0.0到255.0的浮點數組,不能正確顯示顏色 
>>> plt.imshow(img/255.0) #取值範圍爲0.0到1.0的浮點數組,能正確顯示顏色
>>> plt.imshow(np.clip(img/200.0, 0, 1)> # 使用 clip()限制取值範圍,整個圖像變亮
如果imshow()的參數是二維數組,就使用顏色映射表決定每個像素的顏色。下面顯示圖像 中的紅色通道:
>>> plt.imshow(img[:,:,0])
顯示效果比較嚇人,因爲默認的圖像映射將最小值映射爲藍色、將最大值映射爲紅色. 可以使用colorbar()將顏色映射表在圖表中顯示出來:
>>> plt.colorbar()
通過imshow()的cmap參數可以修改顯示圖像時所採用的顏色映射表。顏色映射表是一個 ColorMap對象,matplotlib中已經預先定義好了很多顏色映射表,可通過下面的語句找到這 些顏色映射表的名字:
>>> import matplotlib.cm as cm 
>>> cm._cmapnames
[‘Spectral’,’copper’, ‘RdYlGn', ‘Set2’,’ sumner’, ’spring’,’gist_ncar’,…]
下面使用名爲copper的顏色映射表顯示圖像的紅色通道,很有老照片的味道: 
>>>plt.imshow(img[:,:,0],cmap=cm.copper)
還可以使用imshow()顯示任意的二維數據,例如下面的程序使用圖像直觀地顯示了二元函數:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

y, x = np.ogrid[-2:2:200j, -2:2:200j]
z = x * np.exp( - x**2 - y**2)

extent = [np.min(x), np.max(x), np.min(y), np.max(y)]
plt.figure(figsize=(10,3))
plt.subplot(121)
plt.imshow(z, extent=extent, origin="lower") 
plt.colorbar()
plt.subplot(122)
plt.imshow(z, extent=extent, cmap=cm.gray, origin="lower")
plt.colorbar()

plt.show()
imshow()的extent參數,圖表的X、Y軸的刻度標籤所指定的範圍.



散點圖:

import numpy as np
from pylab import *
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']#用來正常顯示中文標籤
matplotlib.rcParams['axes.unicode_minus']=False#負號不正常顯示問題
fig=plt.figure()
samples_num = 60  
t = np.random.random(size=samples_num) * 2 * np.pi - np.pi  
x2 = np.cos(t)  
y2 = np.sin(t)  
i_set = np.arange(0,samples_num,1)  
for i in i_set:  
    len = np.random.random()*500
    if len < 50:
        len += 350
    x2[i] = x2[i] * len  
    y2[i] = y2[i] * len  
plt.scatter(x2,y2,marker = 'o', color = 'm', label=u'UE', s = 30)
plt.legend(loc='upper left',scatterpoints=1) #設置圖例點的個數
plt.axis([-600,600,-600,600])
#plt.xlim(-600,600)
#plt.ylim(-600,600)
#座標軸字體變大,應對圖片縮小後字體不清晰問題
plt.xlabel(u"x[m]",fontsize=18)
plt.ylabel(u"y[m]",fontsize=18)
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
#plt.title("a simple example")


plt.grid(True)
#plt.legend(numpoints=1)
plt.subplots_adjust(left=0.12, right=0.97, bottom=0.12, top=0.97)
#plt.show()
plt.savefig("scenario.png",dpi=200)#圖片分辨率問題


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