Python畫圖之總結待整理
https://morvanzhou.github.io/tutorials/data-manipulation/plt/
http://blog.sciencenet.cn/blog-1408284-850983.html
http://www.cnblogs.com/DHUtoBUAA/p/6619099.html
http://blog.csdn.net/wuguangbin1230/article/details/72858612
http://blog.sciencenet.cn/blog-251664-800766.html
http://blog.csdn.net/wuguangbin1230/article/details/72858612
http://www.lxweimin.com/p/0a81b57bbb8c
https://pythonprogramming.net/
http://blog.csdn.net/haoji007/article/details/52063168
Seaborn 庫:https://seaborn.pydata.org/
Python Seaborn 教程:http://elitedatascience.com/python-seaborn-tutorial
matplotlib: plotting with Python
matplotlib: plotting with Python-github
python-data-visualization-course
Interactive Web Plotting for Python
Interactive Web Plotting for Python-github
https://morvanzhou.github.io/tutorials/data-manipulation/plt/3-3-contours/
https://github.com/MorvanZhou/tutorials/tree/master/matplotlibTUT
https://github.com/jiandanjinxin/tf-dev-summit-tensorboard-tutorial
https://github.com/jiandanjinxin/tensorflow-mnist-tutorial
matplotlib標準模式
plt.figure(num=5, figsize=(8,5),)
#plt.figure(num='newimage', figsize=(8,5),)
plt.title('The image title', color='#0000FF')
plt.imshow(lena) # 顯示圖片
plt.axis('off') # 不顯示坐標軸
plt.show()
New function:Plotting with matplotlib
%matplotlib inline
%matplotlib notebook
%matplotlib inline
import matplotlib.pyplot as plt
X = np.random.normal(size=(12, 2))
plt.scatter(X[:, 0], X[:, 1])
plt.plot(X[:, 0])
# create a new figure
plt.figure()
plt.plot(X[:, 0])
%matplotlib notebook
import matplotlib.pyplot as plt
X = np.random.normal(size=(12, 2))
plt.scatter(X[:, 0], X[:, 1])
plt.plot(X[:, 0])
# create a new figure
plt.figure()
plt.plot(X[:, 0])
Plotting with matplotlib
Need to use either
% matplotlib inline
or
% matplotlib notebook
Only one in each notebook! using inline
will just sent png
images to browser, using notebook
will provide interactivity and allow updating old figures. With notebook
you need to make sure to create a new figure before plotting, otherwise the last one will be updated!
# 1、顯示圖片
import matplotlib.pyplot as plt #plt 用于顯示圖片
import matplotlib.image as mpimg #mpimg 用于讀取圖片
import numpy as np
lena = mpimg.imread('lena.png') #讀取和代碼處于同一目錄下的lena.png
# 此時 lena 就已經是一個 np.array 了,可以對它進行任意處理
lena.shape #(512, 512, 3)
plt.figure(num=1, figsize=(8,5),)
plt.title('The image title')
plt.imshow(lena) # 顯示圖片
plt.axis('off') # 不顯示坐標軸
plt.show()
# 2、顯示圖片的第一個通道
lena_1 = lena[:,:,0]
plt.figure(num=2, figsize=(8,5),)
plt.imshow('lena_1')
plt.title('The image title')
plt.axis('off')
plt.show()
# 此時會發現顯示的是熱量圖,不是我們預想的灰度圖,可以添加 cmap 參數,有如下幾種添加方法:
#方法一
plt.figure(num=1, figsize=(8,5),)
plt.imshow('lena_1', cmap='Greys_r')
plt.title('The image title')
plt.axis('off')
plt.show()
#方法二
plt.figure(num=2, figsize=(8,5),)
img = plt.imshow('lena_1')
img.set_cmap('gray') # 'hot' 是熱量圖
plt.title('The image title')
plt.axis('off')
plt.show()
#3、將 RGB 轉為灰度圖
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
gray = rgb2gray(lena)
# 也可以用 plt.imshow(gray, cmap = plt.get_cmap('gray'))
plt.figure(num=3, figsize=(8,5),)
plt.imshow(gray, cmap='Greys_r')
plt.title('The image title')
plt.axis('off')
plt.show()
#4、對圖像進行放縮
from scipy import misc
lena_new_sz = misc.imresize(lena, 0.5) # 第二個參數如果是整數,則為百分比,如果是tuple,則為輸出圖像的尺寸
plt.figure(num=4, figsize=(8,5),)
plt.imshow(lena_new_sz)
plt.title('The image title')
plt.axis('off')
plt.show()
附上imresize的用法
功能:改變圖像的大小。
用法:
B = imresize(A,m)
B = imresize(A,m,method)
B = imresize(A,[mrows ncols],method)
B = imresize(...,method,n)
B = imresize(...,method,h)
imrersize函數使用由參數method指定的插值運算來改變圖像的大小。
method的幾種可選值:
'nearest'(默認值)最近鄰插值
'bilinear'雙線性插值
'bicubic'雙三次插值
B = imresize(A,m)表示把圖像A放大m倍
B = imresize(...,method,h)中的h可以是任意一個FIR濾波器(h通常由函數ftrans2、fwind1、fwind2、或fsamp2等生成的二維FIR濾波器)。
#5、保存 matplotlib 畫出的圖像
plt.savefig('lena_new_sz.png')
#5、將 array 保存為圖像
from scipy import misc
misc.imsave('lena_new_sz.png', lena_new_sz)
#5、直接保存 array
#讀取之后還是可以按照前面顯示數組的方法對圖像進行顯示,這種方法完全不會對圖像質量造成損失
np.save('lena_new_sz', lena_new_sz) # 會在保存的名字后面自動加上.npy
img = np.load('lena_new_sz.npy') # 讀取前面保存的數組
matplotlib畫圖清空圖片
fig = plt.figure(0) # 新圖 0
plt.savefig() # 保存
plt. close(0) # 關閉圖 0
還有簡便的 plt.close('all') 關閉所有圖,不用管 fig 號碼
fig = plt.figure() # 新圖 0
plt.savefig() # 保存
plt.close('all') # 關閉圖 0
matplotlib-數據可視化
Some plots from these tutorials:
單個圖像繪制
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(num=1, figsize=(8,5),)
plt.plot(x,y)
plt.show()
多個圖像繪制和同一個figure多個圖片
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3,3,50)
y1 = 2*x
y2 = x**2
plt.figure(num=2, figsize=(8,5),)
plt.plot(x, y1)
plt.show()
plt.figure(num=3, figsize=(8,5),)
plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--)
plt.plot(x,y2)
plt.show()
設置坐標軸1
調整名字和間隔
import matplotlib.pyplot as plt
import numpy as np
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\ \alphas$', r'$normal$', r'$good$', r'$really\ good$'])
plt.show()
#r 正則表達,改變字體加$. \alphas,轉字符\。
設置坐標軸2
設置不同名字和位置
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2
plt.figure()
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--')
plt.xlim((-1, 2))
plt.ylim((-2, 3))
new_ticks = np.linspace(-1, 2, 5)
plt.xticks(new_ticks)
plt.yticks([-2, -1.8, -1, 1.22, 3],['$really\ bad$', '$bad$', '$normal$', '$good$', '$really\ good$'])
#使用plt.gca獲取當前坐標軸信息get current axis. 使用.spines設置邊框:右側邊框;使用.set_color設置邊框顏色:默認白色; 使用.spines設置邊框:上邊框;使用.set_color設置邊框顏色:默認白色;
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()
#spines脊梁,實際上是四個邊框。
調整坐標軸
#使用.xaxis.set_ticks_position設置x坐標刻度數字或名稱的位置:bottom.(所有位置:top,bottom,both,default,none)
ax.xaxis.set_ticks_position('bottom')
#使用.spines設置邊框:x軸;使用.set_position設置邊框位置:y=0的位置;(位置所有屬性:outward,axes,data)
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()
Legend 圖例
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$'])
#本節中我們將對圖中的兩條線繪制圖例,首先我們設置兩條線的類型等信息(藍色實線與紅色虛線).
l1, = plt.plot(x, y2, label='linear line')
l2, = plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--', label='square line')
#egend將要顯示的信息來自于上面代碼中的 label. 所以我們只需要簡單寫下一下代碼, plt 就能自動的為我們添加圖例.
plt.legend(loc='upper right')
參數loc='upper right'
表示圖例將添加在圖中的右上角.
調整位置和名稱
#如果我們想單獨修改之前的 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')
# the "," is very important in here l1, = plt... and l2, = plt... for this step
"""legend( handles=(line1, line2, line3),
labels=('label1', 'label2', 'label3'),
'upper right')
The *loc* location codes are::
'best' : 0, (currently not supported for figure legends)
'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,"""
plt.show()
最后我們得到帶有圖例信息的圖片.
Annotation 標注
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.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)#虛線, k代表黑色 -- 虛線
plt.scatter([x0, ], [y0, ], s=50, color='b')# 散點圖
添加注釋 annotate
接下來我們就對(x0, y0)這個點進行標注.
# method 1:
#####################
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
是對圖中箭頭類型的一些設置.
添加注釋 text
# method 2:
########################
plt.text(-3.7, 3, r'$This\ is\ the\ some\ text. \mu\ \sigma_i\ \alpha_t$',
fontdict={'size': 16, 'color': 'r'})
plt.show()
其中-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()
plt.plot(x, y, linewidth=10)
plt.ylim(-2, 2)
ax = plt.gca()
ax.spines['right'].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)
label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.7))
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':
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把顏色加進去,fill, 位置參數分別為:X, Y, f(X,Y)。透明度0.75,并將 f(X,Y) 的值對應到color map的暖色組中尋找對應顏色。8代表等高線的個數。
# 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(())
plt.clabel(C, inline=False, fontsize=10)
plt.xticks(())
plt.yticks(())
Image 圖片
隨機矩陣畫圖
這一節我們講解怎樣在matplotlib中打印出圖像。這里我們打印出的是純粹的數字,而非自然圖像。 我們今天用這樣 3x3 的 2D-array 來表示點的顏色,每一個點就是一個pixel。
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)
plt.imshow(a, interpolation='nearest', cmap='bone', origin='lower')
plt.imshow(a, interpolation='nearest', cmap='bone', origin='upper')
colorbar
下面我們添加一個colorbar ,其中我們添加一個shrink參數,使colorbar的長度變短為原來的92%:
plt.colorbar(shrink=.92)
plt.xticks(())
plt.yticks(())
plt.show()
3D 數據
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)
接下來給進 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)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))
其中,rstride 和 cstride 分別代表 row 和 column 的跨度。
下面兩個圖分別是跨度為1 和 5 的效果:
投影
下面添加 XY 平面的等高線:
ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap=plt.get_cmap('rainbow'))
ax.set_zlim(-2, 2)
ax.contourf(X, Y, Z, zdir='x', offset=-4, cmap=plt.get_cmap('rainbow'))
plt.show()
如果 zdir 選擇了x,那么效果將會是對于 XZ 平面的投影,效果如下
Subplot 多合一顯示
均勻圖中圖
matplotlib 是可以組合許多的小圖, 放在一張大圖里面顯示的. 使用到的方法叫作 subplot.
使用import導入matplotlib.pyplot模塊, 并簡寫成plt. 使用plt.figure創建一個圖像窗口.
import matplotlib.pyplot as plt
plt.figure()
使用plt.subplot來創建小圖. plt.subplot(2,2,1)表示將整個圖像窗口分為2行2列, 當前位置為1. 使用plt.plot([0,1],[0,1])在第1個位置創建一個小圖.
plt.subplot(2,2,2)表示將整個圖像窗口分為2行2列, 當前位置為2. 使用plt.plot([0,1],[0,2])在第2個位置創建一個小圖.
plt.subplot(2,2,3)表示將整個圖像窗口分為2行2列,當前位置為3. plt.subplot(2,2,3)可以簡寫成plt.subplot(223), matplotlib同樣可以識別. 使用plt.plot([0,1],[0,3])在第3個位置創建一個小圖.
plt.subplot(224)表示將整個圖像窗口分為2行2列, 當前位置為4. 使用plt.plot([0,1],[0,4])在第4個位置創建一個小圖.
plt.subplot(2,2,1)
plt.plot([0,1],[0,1])
plt.subplot(2,2,2)
plt.plot([0,1],[0,2])
plt.subplot(223)
plt.plot([0,1],[0,3])
plt.subplot(224)
plt.plot([0,1],[0,4])
plt.show() # 展示
不均勻圖中圖
如果希望展示的小圖的大小不相同, 應該怎么做呢? 以上面的4個小圖為例, 如果把第1個小圖放到第一行, 而剩下的3個小圖都放到第二行.
使用plt.subplot(2,1,1)將整個圖像窗口分為2行1列, 當前位置為1. 使用plt.plot([0,1],[0,1])在第1個位置創建一個小圖.
使用plt.subplot(2,3,4)將整個圖像窗口分為2行3列, 當前位置為4. 使用plt.plot([0,1],[0,2])在第4個位置創建一個小圖.
這里需要解釋一下為什么第4個位置放第2個小圖. 上一步中使用plt.subplot(2,1,1)將整個圖像窗口分為2行1列, 第1個小圖占用了第1個位置, 也就是整個第1行. 這一步中使用plt.subplot(2,3,4)將整個圖像窗口分為2行3列, 于是整個圖像窗口的第1行就變成了3列, 也就是成了3個位置, 于是第2行的第1個位置是整個圖像窗口的第4個位置.
使用plt.subplot(235)將整個圖像窗口分為2行3列,當前位置為5. 使用plt.plot([0,1],[0,3])在第5個位置創建一個小圖. 同上, 再創建plt.subplot(236).
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(2,1,1)
plt.plot([0,1],[0,1])
plt.subplot(2,3,4)
plt.plot([0,1],[0,2])
plt.subplot(235)
plt.plot([0,1],[0,3])
plt.subplot(236)
plt.plot([0,1],[0,4])
plt.show() # 展示
Subplot 分格顯示
subplot2grid
使用import導入matplotlib.pyplot模塊, 并簡寫成plt. 使用plt.figure()創建一個圖像窗口
import matplotlib.pyplot as plt
plt.figure()
使用plt.subplot2grid來創建第1個小圖, (3,3)表示將整個圖像窗口分成3行3列, (0,0)表示從第0行第0列開始作圖,colspan=3表示列的跨度為3, rowspan=1表示行的跨度為1. colspan和rowspan缺省, 默認跨度為1.
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax1.plot([1, 2], [1, 2]) # 畫小圖
ax1.set_title('ax1_title') # 設置小圖的標題
使用plt.subplot2grid來創建第2個小圖, (3,3)表示將整個圖像窗口分成3行3列, (1,0)表示從第1行第0列開始作圖,colspan=2表示列的跨度為2. 同上畫出 ax3, (1,2)表示從第1行第2列開始作圖,rowspan=2表示行的跨度為2. 再畫一個 ax4 和 ax5, 使用默認 colspan, rowspan.
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))
使用ax4.scatter創建一個散點圖, 使用ax4.set_xlabel和ax4.set_ylabel來對x軸和y軸命名.
ax4.scatter([1, 2], [2, 2])
ax4.set_xlabel('ax4_x')
ax4.set_ylabel('ax4_y')
gridspec
使用import導入matplotlib.pyplot模塊, 并簡寫成plt. 使用import導入matplotlib.gridspec, 并簡寫成gridspec
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
使用plt.figure()創建一個圖像窗口, 使用gridspec.GridSpec將整個圖像窗口分成3行3列.
plt.figure()
gs = gridspec.GridSpec(3, 3)
使用plt.subplot來作圖, gs[0, :]表示這個圖占第0行和所有列, gs[1, :2]表示這個圖占第1行和第2列前的所有列, gs[1:, 2]表示這個圖占第1行后的所有行和第2列, gs[-1, 0]表示這個圖占倒數第1行和第0列, gs[-1, -2]表示這個圖占倒數第1行和倒數第2列.
ax6 = plt.subplot(gs[0, :])
ax7 = plt.subplot(gs[1, :2])
ax8 = plt.subplot(gs[1:, 2])
ax9 = plt.subplot(gs[-1, 0])
ax10 = plt.subplot(gs[-1, -2])
subplots
使用plt.subplots建立一個2行2列的圖像窗口,sharex=True表示共享x軸坐標, sharey=True表示共享y軸坐標. ((ax11, ax12), (ax13, ax14))表示第1行從左至右依次放ax11和ax12, 第2行從左至右依次放ax13和ax14.
f, ((ax11, ax12), (ax13, ax14)) = plt.subplots(2, 2, sharex=True, sharey=True)
使用ax11.scatter創建一個散點圖.
ax11.scatter([1,2], [1,2])
plt.tight_layout()表示緊湊顯示圖像, plt.show()表示顯示圖像.
plt.tight_layout()
plt.show()
圖中圖
數據
# 導入pyplot模塊
import matplotlib.pyplot as plt
# 初始化figure
fig = plt.figure()
# 創建數據
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 3, 4, 2, 5, 8, 6]
大圖
接著,我們來繪制大圖。首先確定大圖左下角的位置以及寬高:
left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
注意,4個值都是占整個figure坐標系的百分比。在這里,假設figure的大小是10x10,那么大圖就被包含在由(1, 1)開始,寬8,高8的坐標系內。
將大圖坐標系添加到figure中,顏色為r(red),取名為title:
ax1 = fig.add_axes([left, bottom, width, height])
ax1.plot(x, y, 'r')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_title('title')
小圖
接著,我們來繪制左上角的小圖,步驟和繪制大圖一樣,注意坐標系位置和大小的改變:
eft, bottom, width, height = 0.2, 0.6, 0.25, 0.25
ax2 = fig.add_axes([left, bottom, width, height])
ax2.plot(y, x, 'b')
ax2.set_xlabel('x')
ax2.set_ylabel('y')
ax2.set_title('title inside 1')
最后,我們來繪制右下角的小圖。這里我們采用一種更簡單方法,即直接往plt里添加新的坐標系:
plt.axes([0.6, 0.2, 0.25, 0.25])
plt.plot(y[::-1], x, 'g') # 注意對y進行了逆序處理
plt.xlabel('x')
plt.ylabel('y')
plt.title('title inside 2')
plt.show()
次坐標軸
第一個y坐標
有時候我們會用到次坐標軸,即在同個圖上有第2個y軸存在。同樣可以用matplotlib做到,而且很簡單。
首先,我們做一些準備工作:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y1 = 0.05 * x**2
y2 = -1 * y1
可以看到,y2和y1是互相倒置的。接著,獲取figure默認的坐標系 ax1:
fig, ax1 = plt.subplots()
第二個y坐標
對ax1調用twinx()方法,生成如同鏡面效果后的ax2:
ax2 = ax1.twinx()
接著進行繪圖, 將 y1, y2 分別畫在 ax1, ax2 上:
ax1.plot(x, y1, 'g-') # green, solid line
ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='g')
ax2.plot(x, y2, 'b-') # blue
ax2.set_ylabel('Y2 data', color='b')
plt.show()
Animation 動畫
定義方程
使用matplotlib做動畫也是可以的,我們使用其中一種方式,function animation來說說,具體可參考matplotlib animation api。首先,我們做一些準備工作:
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
fig, ax = plt.subplots()
我們的數據是一個0~2π內的正弦曲線:
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))
接著,構造自定義動畫函數animate,用來更新每一幀上各個x對應的y坐標值,參數表示第i幀
def animate(i):
line.set_ydata(np.sin(x + i/10.0))
return line,
然后,構造開始幀函數init:
def init():
line.set_ydata(np.sin(x))
return line,
參數設置
接下來,我們調用FuncAnimation函數生成動畫。參數說明:
fig 進行動畫繪制的figure
func 自定義動畫函數,即傳入剛定義的函數animate
frames 動畫長度,一次循環包含的幀數
init_func 自定義開始幀,即傳入剛定義的函數init
interval 更新頻率,以ms計
blit 選擇更新所有點,還是僅更新產生變化的點。應選擇True,但mac用戶請選擇False,否則無法顯示動畫
ani = animation.FuncAnimation(fig=fig,
func=animate,
frames=100,
init_func=init,
interval=20,
blit=False)
plt.show()
當然,你也可以將動畫以mp4格式保存下來,但首先要保證你已經安裝了ffmpeg
或者mencoder
,更多信息參考matplotlib animation api:
anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])