【莫煩】Python Matplotlib

Amor167發表於2019-02-06

基本用法

import matplotlib.pyplot as plt
import numpy as np
# 使用np.linspace定義x:範圍是(-1,1);個數是50. 模擬一維資料組(x ,y)表示曲線1.

x = np.linspace(-1, 1, 50)
y = 2*x + 1
#使用plt.figure定義一個影象視窗. 使用plt.plot畫(x ,y)曲線. 使用plt.show顯示影象.

plt.figure()# 建立一個圖形例項
plt.plot(x, y)
plt.show()

在這裡插入圖片描述

figure 影象

簡單的線條

matplotlib 的 figure 就是一個 單獨的 figure 小視窗, 小視窗裡面還可以有更多的小圖片.

使用import匯入模組matplotlib.pyplot,並簡寫成plt 使用import匯入模組numpy,並簡寫成np

import matplotlib.pyplot as plt
import numpy as np
# 使用np.linspace定義x:範圍是(-3,3);個數是50. 模擬一維資料組(x ,y1)表示曲線1. 模擬一維資料組(x ,y2)表示曲線2.

x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2
# 使用plt.figure定義一個影象視窗. 使用plt.plot畫(x ,y1)曲線.

plt.figure()
plt.plot(x, y1)
plt.show()

在這裡插入圖片描述

使用plt.figure定義一個影象視窗:編號為3;大小為(8, 5). 使用plt.plot畫(x ,y2)曲線. 使用plt.plot畫(x ,y1)曲線,曲線的顏色屬性(color)為紅色;曲線的寬度(linewidth)為1.0;曲線的型別(linestyle)為虛線. 使用plt.show顯示影象.

plt.figure(num=3, figsize=(8, 5),)
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--')
plt.show()

在這裡插入圖片描述

設定座標軸

調整名字和間隔

import matplotlib.pyplot as plt
import numpy as np
# 使用np.linspace定義x:範圍是(-3,3);個數是50. 模擬一維資料組(x ,y1)表示曲線1. 模擬一維資料組(x ,y2)表示曲線2.

x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2
#使用plt.figure定義一個影象視窗. 使用plt.plot畫(x ,y2)曲線. 使用plt.plot畫(x ,y1)曲線,曲線的顏色屬性(color)為紅色;曲線的寬度(linewidth)為1.0;曲線的型別(linestyle)為虛線.

plt.figure()
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--')
#使用plt.xlim設定x座標軸範圍:(-1, 2); 使用plt.ylim設定y座標軸範圍:(-2, 3); 使用plt.xlabel設定x座標軸名稱:’I am x’; 使用plt.ylabel設定y座標軸名稱:’I am y’;

plt.xlim((-1, 2))
plt.ylim((-2, 3))
plt.xlabel('I am x')
plt.ylabel('I am y')
plt.show()

在這裡插入圖片描述

#使用np.linspace定義範圍以及個數:範圍是(-1,2);個數是5. 
#使用print列印出新定義的範圍. 
#使用plt.xticks設定x軸刻度:範圍是(-1,2);個數是5.

new_ticks = np.linspace(-1, 2, 5)
print(new_ticks)
plt.xticks(new_ticks)
#使用plt.yticks設定y軸刻度以及名稱:刻度為[-2, -1.8, -1, 1.22, 3];對應刻度的名稱為[‘really bad’,’bad’,’normal’,’good’, ‘really good’].  $ $數學形式的字母更好看 空格需要用\註釋
#使用plt.show顯示影象.
plt.yticks([-2, -1.8, -1, 1.22, 3],[r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])
plt.show()

在這裡插入圖片描述

設定不同名字和位置


使用plt.gca獲取當前座標軸資訊. 使用.spines設定邊框:右側邊框;使用.set_color設定邊框顏色:預設白色; 使用.spines設定邊框:上邊框;使用.set_color設定邊框顏色:預設白色;

ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()

在這裡插入圖片描述

調整座標軸

#使用.xaxis.set_ticks_position設定x座標刻度數字或名稱的位置:bottom.(所有位置:top,bottom,both,default預設值,none)(both-ticks to appear on both positions, but does not change the tick labels. 'default' - ticks on both positions, labels at bottom. 'none' -no ticks. 'none' and 'both' affect only the ticks, not the labels.)

#使用.spines設定邊框:x軸;
#使用.set_position設定邊框位置:y=0的位置;(位置所有屬性:outward,axes,data)

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
plt.show()

在這裡插入圖片描述

使用.yaxis.set_ticks_position設定y座標刻度數字或名稱的位置:left.(所有位置:left,right,both,default,none)

ax.yaxis.set_ticks_position('left')
#使用.spines設定邊框:y軸;使用.set_position設定邊框位置:x=0的位置;(位置所有屬性:outward,axes,data) 使用plt.show顯示影象.

ax.spines['left'].set_position(('data',0))
plt.show()

新增圖例

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2

plt.figure()
#set x limits
plt.xlim((-1, 2))
plt.ylim((-2, 3))

# set new sticks
new_sticks = np.linspace(-1, 2, 5)
plt.xticks(new_sticks)
# set tick labels
plt.yticks([-2, -1.8, -1, 1.22, 3],
           [r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])

本節中我們將對圖中的兩條線繪製圖例,首先我們設定兩條線的型別等資訊(藍色實線與紅色虛線).

# set line syles
l1, = plt.plot(x, y1, label='linear line')
l2, = plt.plot(x, y2, color='red', linewidth=1.0, linestyle='--', label='square line')

legend將要顯示的資訊來自於上面程式碼中的 label. 所以我們只需要簡單寫下一下程式碼, plt 就能自動的為我們新增圖例.

plt.legend(loc='upper right')

引數 loc=‘upper right’ 表示圖例將新增在圖中的右上角. Legend 圖例

調整位置和名稱

如果我們想單獨修改之前的 label 資訊, 給不同型別的線條設定圖例資訊. 我們可以在 plt.legend 輸入更多引數. 如果以下面這種形式新增 legend, 我們需要確保, 在上面的程式碼 plt.plot(x, y2, label=‘linear line’) 和 plt.plot(x, y1, label=‘square line’) 中有用變數 l1 和 l2 分別儲存起來. 而且需要注意的是 l1, l2,要以逗號結尾, 因為plt.plot() 返回的是一個列表.

plt.legend(handles=[l1, l2], labels=['up', 'down'],  loc='best')

這樣我們就能分別重新設定線條對應的 label 了.

最後我們得到帶有圖例資訊的圖片.
在這裡插入圖片描述
其中’loc’引數有多種,’best’表示自動分配最佳位置,其餘的如下:

 'best' : 0,          
 'upper right'  : 1,
 'upper left'   : 2,
 'lower left'   : 3,
 'lower right'  : 4,
 'right'        : 5,
 'center left'  : 6,
 'center right' : 7,
 'lower center' : 8,
 'upper center' : 9,
 'center'       : 10,

Annotation 標註

當圖線中某些特殊地方需要標註時,我們可以使用 annotation. matplotlib 中的 annotation 有兩種方法, 一種是用 plt 裡面的 annotate,一種是直接用 plt 裡面的 text 來寫標註.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y = 2*x + 1

plt.figure(num=1, figsize=(8, 5),)
plt.plot(x, y,)

#移動座標 
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))

然後標註出點(x0, y0)的位置資訊. 用plt.plot([x0, x0,], [0, y0,], ‘k–’, linewidth=2.5) 畫出一條垂直於x軸的虛線.

x0 = 1
y0 = 2*x0 + 1
plt.plot([x0, x0,], [0, y0,], 'k--', linewidth=2.5)
# set dot styles
plt.scatter([x0, ], [y0, ], s=50, color='b')

在這裡插入圖片描述

新增註釋 annotate ¶

接下來我們就對(x0, y0)這個點進行標註.

plt.annotate(r'$2x+1=%s$' % y0, xy=(x0, y0), xycoords='data', xytext=(+30, -30),
             textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=.2"))

其中引數xycoords=‘data’ 是說基於資料的值來選位置, xytext=(+30, -30) 和 textcoords=‘offset points’ 對於標註位置的描述 和 xy 偏差值, arrowprops是對圖中箭頭型別的一些設定.
Annotation 標註

新增註釋 text

plt.text(-3.7, 3, r'$This\ is\ the\ some\ text. \mu\ \sigma_i\ \alpha_t$',
         fontdict={'size': 16, 'color': 'r'})

其中-3.7, 3,是選取text的位置, 空格需要用到轉字元\ ,fontdict設定文字字型.
在這裡插入圖片描述

座標軸tick 能見度

當圖片中的內容較多,相互遮蓋時,我們可以通過設定相關內容的透明度來使圖片更易於觀察,也即是通過本節中的bbox引數設定來調節影象資訊.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y = 0.1*x

plt.figure()
#設定zorder給plot在z軸方向排序即設定畫的先後順序,zorder值低的先畫
plt.plot(x, y, linewidth=10, zorder=1)
plt.ylim(-2, 2)
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))

在這裡插入圖片描述

調整座標

然後對被遮擋的影象調節相關透明度,本例中設定 x軸 和 y軸 的刻度數字進行透明度設定

for label in ax.get_xticklabels() + ax.get_yticklabels():
    label.set_fontsize(12)
# 在 plt 2.0.2 或更高的版本中, 設定 zorder 給 plot 在 z 軸方向排序
    label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.7, zorder=2))
plt.show()

其中label.set_fontsize(12)重新調節字型大小,bbox設定目的內容的透明度相關參,facecolor調節 box 前景色,edgecolor 設定邊框, 本處設定邊框為無,alpha設定透明度. 最終結果如下:
在這裡插入圖片描述

Scatter 散點圖

首先,先引入matplotlib.pyplot簡寫作plt,再引入模組numpy用來產生一些隨機資料。生成1024個呈標準正態分佈的二維資料組 (平均數是0,方差為1) 作為一個資料集,並影象化這個資料集。每一個點的顏色值用T來表示:

import matplotlib.pyplot as plt
import numpy as np

n = 1024    # data size
X = np.random.normal(0, 1, n) # 每一個點的X值
Y = np.random.normal(0, 1, n) # 每一個點的Y值
T = np.arctan2(Y,X) # for color value

資料集生成完畢,現在來用scatterplot這個點集,滑鼠點上去,可以看到這個函式的各個parameter的描述,如下圖:
在這裡插入圖片描述
輸入X和Y作為location,size=75,顏色為T,color map用預設值,透明度alpha 為 50%。 x軸顯示範圍定位(-1.5,1.5),並用xtick()函式來隱藏x座標軸,y軸同理:

plt.scatter(X, Y, s=75, c=T, alpha=.5)

plt.xlim(-1.5, 1.5)
plt.xticks(())  # ignore xticks
plt.ylim(-1.5, 1.5)
plt.yticks(())  # ignore yticks

plt.show()

在這裡插入圖片描述

Bar 柱狀圖

向上向下分別生成12個資料,X為 0 到 11 的整數 ,Y是相應的均勻分佈的隨機資料。 使用的函式是plt.bar,引數為X和Y:

import matplotlib.pyplot as plt
import numpy as np

n = 12
X = np.arange(n)
Y1 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)
Y2 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)

plt.bar(X, +Y1)
plt.bar(X, -Y2)

plt.xlim(-.5, n)
plt.xticks(())
plt.ylim(-1.25, 1.25)
plt.yticks(())

plt.show()

這樣我們就生成了下圖所示的柱狀圖基本框架:
在這裡插入圖片描述

加顏色和資料

下面我們就顏色和數值進行優化。 用facecolor設定主體顏色,edgecolor設定邊框顏色為白色,

plt.bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
plt.bar(X, -Y2, facecolor='#ff9999', edgecolor='white')

在這裡插入圖片描述
接下來我們用函式plt.text分別在柱體上方(下方)加上數值,用%.2f保留兩位小數,橫向居中對齊ha=‘center’,縱向底部(頂部)對齊va=‘bottom’:
zip生成元組迭代器

for x, y in zip(X, Y1):
    # ha: horizontal alignment
    # va: vertical alignment
    plt.text(x + 0.4, y + 0.05, '%.2f' % y, ha='center', va='bottom')

for x, y in zip(X, Y2):
    # ha: horizontal alignment
    # va: vertical alignment
    plt.text(x + 0.4, -y - 0.05, '%.2f' % y, ha='center', va='top')

在這裡插入圖片描述

Contours 等高線圖

資料集即三維點 (x,y) 和對應的高度值,共有256個點。高度值使用一個 height function f(x,y) 生成。 x, y 分別是在區間 [-3,3] 中均勻分佈的256個值,並用meshgrid在二維平面中將每一個x和每一個y分別對應起來,編織成柵格:

import matplotlib.pyplot as plt
import numpy as np

def f(x,y):
    # the height function
    return (1 - x / 2 + x**5 + y**3) * np.exp(-x**2 -y**2)

n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X,Y = np.meshgrid(x, y)

顏色填充。

使用函式plt.contourf把顏色加進去,位置引數分別為:X, Y, f(X,Y)。透明度0.75,並將 f(X,Y) 的值對應到color map的暖色組中尋找對應顏色。

# use plt.contourf to filling contours
# X, Y and value for (X,Y) point
plt.contourf(X, Y, f(X, Y), 8, alpha=.75, cmap=plt.cm.hot)

等高線繪製。

使用plt.contour函式劃線。位置引數為:X, Y, f(X,Y)。顏色選黑色,線條寬度選0.5。現在的結果如下圖所示,只有顏色和線條,還沒有數值Label:

# use plt.contour to add contour lines
C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=.5)

新增高度數字

其中,8代表等高線的密集程度,這裡被分為10個部分。如果是0,則影象被一分為二。

最後加入Label,inline控制是否將Label畫線上裡面,字型大小為10。並將座標軸隱藏:

plt.clabel(C, inline=True, fontsize=10)
plt.xticks(())
plt.yticks(())

最終結果即:
在這裡插入圖片描述

Image 圖片

隨機矩陣畫圖
這一節我們講解怎樣在matplotlib中列印出影象。這裡我們列印出的是純粹的數字,而非自然影象。 我們今天用這樣 3x3 的 2D-array 來表示點的顏色,每一個點就是一個pixel。
相當於每一個2D-array中的點就是一個畫素點,用值來代表顏色

import matplotlib.pyplot as plt
import numpy as np

a = np.array([0.313660827978, 0.365348418405, 0.423733120134,
              0.365348418405, 0.439599930621, 0.525083754405,
              0.423733120134, 0.525083754405, 0.651536351379]).reshape(3,3)

今天做出的影象就是這個樣子:
Image 圖片

三行三列的格子,a代表每一個值,影象右邊有一個註釋,白色代表值最大的地方,顏色越深值越小。

下面我們來看程式碼:

plt.imshow(a, interpolation='nearest', cmap='bone', origin='lower')

我們之前選cmap的引數時用的是:cmap=plt.cmap.bone,而現在,我們可以直接用單引號傳入引數。 origin='lower’代表的就是選擇的原點的位置。可以選擇upper則會反過來

出圖方式

我們在這個連結 可以看到matplotlib官網上對於內插法的不同方法的描述。下圖是一個示例:
Image 圖片
這裡我們使用的是內插法中的 Nearest-neighbor 的方法,其他的方式也都可以隨意取選。

colorbar

下面我們新增一個colorbar ,其中我們新增一個shrink引數,使colorbar的長度變短為原來的92%:

plt.colorbar(shrink=.92)

plt.xticks(())
plt.yticks(())
plt.show()

這樣我們2D影象就建立完畢了。
在這裡插入圖片描述

3D 圖

首先在進行 3D Plot 時除了匯入 matplotlib ,還要額外新增一個模組,即 Axes 3D 3D 座標軸顯示:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

之後要先定義一個影象視窗,在視窗上新增3D座標軸,顯示成下圖:

fig = plt.figure()
ax = Axes3D(fig)

3D 資料

接下來給進 X 和 Y 值,並將 X 和 Y 編織成柵格。每一個(X, Y)點對應的高度值我們用下面這個函式來計算。

# X, Y value
X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y)    # x-y 平面的網格
R = np.sqrt(X ** 2 + Y ** 2)
# height value
Z = np.sin(R)

今天的結果是這樣的:
3D 資料

做出一個三維曲面,並將一個 colormap rainbow 填充顏色,之後將三維影象投影到 XY 平面上做一個等高線圖。 plot 3D 影象:

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))
ax.plot_wireframe(X, Y, Z, rstride=1, cstride=1,color='black',linewidth=0.5)

其中,rstride 和 cstride 分別代表 row 和 column 的跨度。
下面兩個圖分別是跨度為1 和 5 的效果:
在這裡插入圖片描述
在這裡插入圖片描述

投影

下面新增 XY 平面的等高線:

ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap=plt.get_cmap('rainbow'))

如果 zdir 選擇了x,那麼效果將會是對於 XZ 平面的投影,效果如下:
3D 資料

相關文章