06-Matplotlib
一.圖片灰度處理
導包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
# 讀取圖片
jin = plt.imread('jinzhengen.png')
plt.imshow(jin)
jin.shape
輸出:
(273, 411, 3)
3種方法
# 1, 最大值法
jin_max = jin.max(axis=-1)
jin_max.shape
輸出:
(273, 411)
plt.imshow(jin_max, cmap='gray')
plt.axis('off')
# 作為對比,使用最小值
jin_min = jin.min(axis=-1)
plt.imshow(jin_min, cmap='gray')
# 2,平均值
jin_mean = jin.mean(axis=-1)
plt.imshow(jin_mean,cmap='gray')
# 3,加權平均, 根據人眼對顏色敏感程度.
# [0.299,0.587,0.114]
jin_weight = np.dot(jin, np.array([0.299,0.587,0.114])) / 3
plt.imshow(jin_weight, cmap='gray')
二.Matplotlib基礎知識
導包
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
2.1 Matplotlib中的基本圖表包括的元素
x軸和y軸
水平和垂直的軸線
x軸和y軸刻度
刻度標示座標軸的分隔,包括最小刻度和最大刻度
x軸和y軸刻度標籤
表示特定座標軸的值
繪圖區域
實際繪圖的區域
2.2 畫曲線
- 一條曲線
n = np.random.randint(0,10, size=10)
plt.plot(n)
- 多條曲線
1、可以使用多個plot函式(推薦),在一個圖中繪製多個曲線
x = np.linspace(-np.pi, np.pi, 100)
y = np.sin(x)
z = np.cos(x)
plt.plot(x, y)
2、也可以在一個plot函式中傳入多對X,Y值,在一個圖中繪製多個曲線
plt.plot(x,y, x,z)
2.3 網格線
使用plt.grid(True)方法為圖新增網格線
lw代表linewidth,線的粗細
alpha表示線的明暗程度
color代表顏色
方法一
plt.figure(figsize=(3*5, 5))
axes1 = plt.subplot(131) # plt.subplot(1,3,1) 返回一個軸面
# 要在這個創造出來的軸面中畫圖
x = np.linspace(-20,20, 1000)
axes1.plot(x, np.sin(x))
axes1.grid(True, linewidth=2, axis='both')
axes2 = plt.subplot(1,3,2)
axes2.plot(x, np.cos(x))
# alpha是線的透明度.
axes2.grid(True, color='r', alpha=0.6)
axes3 = plt.subplot(1,3,3)
axes3.plot(x, x**2)
# linestyple是線的風格
axes3.grid(True, color='g', linestyle='--', alpha=0.7)
方法二
# 通過figure物件來建立子圖
figure = plt.figure(figsize=(3*5, 5))
axes1 = figure.add_subplot(1,3,1)
x = np.linspace(-20,20, 1000)
axes1.plot(x, np.sin(x))
axes1.grid(True, linewidth=2, axis='both')
axes2 = plt.subplot(1,3,2)
axes2.plot(x, np.cos(x))
# alpha是線的透明度.
axes2.grid(True, color='r', alpha=0.6)
axes3 = plt.subplot(1,3,3)
axes3.plot(x, x**2)
# linestyple是線的風格
axes3.grid(True, color='g', linestyle='--', alpha=0.7)
2.4 座標軸界限axis方法設定
如果axis方法沒有任何引數,則返回當前座標軸的上下限axis(xmin =,ymax = )
plt.axis('xxx') 'tight'、'off'、'equal'……
x = np.linspace(-np.pi, np.pi, 100)
y = np.sin(x)
plt.plot(x,y)
# axis什麼也不傳,返回的是當前圖形的座標軸的界限.
plt.axis()
plt.plot(x,y)
# 通過axis方法來設定座標軸的界限
plt.axis([-np.pi, np.pi, -1,1])
plt.plot(x,y)
# tight是axis預設的樣式,緊緻的樣式
# plt.axis('tight')
# off關閉座標軸, 經常用在顯示圖片上.
# plt.axis('off')
# 設定equal, 把畫布的長寬設定成一樣大
plt.axis('equal')
除了plt.axis方法,還可以通過xlim,ylim方法設定座標軸範圍
plt.plot(x,y)
# 單獨設定y軸的界限
# plt.ylim(ymin=-1, ymax=1)
plt.ylim((-1,1))
# xlim設定x軸界限
plt.xlim(-np.pi, np.pi)
2.5 座標軸標籤
xlabel方法和ylabel方法
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
axes = plt.subplot(1,1,1)
line, = axes.plot(x,y)
# 設定x軸標籤
# plt.xlabel('這是x軸', fontdict=dict(fontsize=20))
# 使用物件的set_xlabel方法,檢視全部引數
axes.set_xlabel('這是X軸', fontdict=dict(fontsize=20))
axes = plt.subplot(1,1,1)
line, = axes.plot(x,y)
# 設定x軸標籤
# plt.xlabel('這是x軸', fontdict=dict(fontsize=20))
# 使用物件的set_xlabel方法,檢視全部引數
ylabel = axes.set_ylabel('這是Y軸', fontdict=dict(fontsize=20), rotation=0, position=(0,1))
ylabel.set_alpha(0.5)
ylabel.set_bbox(dict(facecolor='red', alpha=0.5))
2.6 座標軸標題
title方法
plt.plot(x,y)
title = plt.title('這是一個正弦', fontdict=dict(fontsize=20), loc='right')
2.7 圖例legend
legend方法
兩種傳參方法:
1.【推薦使用】在plot函式中增加label引數
2.在legend方法中傳入字串列表
x = np.linspace(0,10, 100)
y1 = 2*x
# label中的字串不能用下劃線開頭, 加了下劃線開頭的圖裂將不會顯示.
plt.plot(x,y1, label='_fast')
plt.plot(x,x, label='normal')
plt.plot(x, 0.5*x, label='slow')
# 兩種方法設定圖例
# 第一種, 在畫圖的時候,指定label, 再呼叫legend方法
plt.legend()
# 第二種方法
# 不需要在建立圖形的時候寫label
x = np.linspace(0,10, 100)
y1 = 2*x
plt.plot(x,y1)
plt.plot(x,x)
plt.plot(x, 0.5*x)
# 通過legend方法傳入一個列表,分別表示對不同的圖形的說明
plt.legend(['fast', 'normal', 'slow'])
-
loc引數
x = np.linspace(0,10, 100)
y1 = 2*x
plt.plot(x,y1)
plt.plot(x,x)
plt.plot(x, 0.5*x)
# 通過legend方法傳入一個列表,分別表示對不同的圖形的說明
plt.legend(['fast', 'normal', 'slow'], loc=5)
2.8 ncol引數
ncol控制圖例中有幾列
x = np.linspace(0,10, 100)
y1 = 2*x
plt.plot(x,y1)
plt.plot(x,x)
plt.plot(x, 0.5*x)
# 通過legend方法傳入一個列表,分別表示對不同的圖形的說明
plt.legend(['fast', 'normal', 'slow'], loc=(0,1), ncol=3)
2.9 linestyle、color、marker
修改線條樣式
2.10 儲存圖片
figure.savefig的選項:
filename:含有檔案路徑的字串或Python的檔案型物件。影像格式由副檔名推斷得出,例如,.pdf推斷出PDF,.png推斷出PNG (“png”、“pdf”、“svg”、“ps”、“eps”……)
dpi:影像解析度(每英寸點數),預設為100
facecolor:影像的背景色,預設為“w”(白色)
n1 = np.random.normal(loc=0, scale=2 ,size=100)
n2 = np.random.normal(loc=10, scale=3, size=100)
n3 = np.random.normal(loc=20,scale=5, size=100)
# 點的形狀叫做點型, marker
figure = plt.figure(figsize=(12,9))
plt.plot(n1, label='one', linestyle='-.', marker='d', markersize=10)
plt.plot(n2, label='two', linestyle='--', marker='o')
plt.plot(n3, label='three', linestyle=':', marker='*', markersize=20)
plt.legend()
figure.savefig('art.jpg', dpi=500, facecolor='r', transparent=True)
三.設定plot的風格和樣式
3.1 點和線的樣式
-
顏色
引數color或c
x = np.linspace(-10, 10, 1000)
plt.plot(x, np.sin(x), c='r')
- 透明度
alpha引數
x = np.linspace(-10, 10, 1000)
# 透明度一般0到1就夠了.
plt.plot(x, np.sin(x), c='r', alpha=0.8)
- 背景色
設定背景色,通過plt.subplot()方法傳入facecolor引數,來設定座標軸的背景色
axes = plt.subplot(1,1,1, facecolor='g')
x = np.linspace(-10, 10, 1000)
# 透明度一般0到1就夠了.
plt.plot(x, np.sin(x), c='r', alpha=0.8)
-
線型
引數linestyle或ls
x = np.linspace(-1, 1 ,1000)
y = (1-x**2)**0.5
plt.plot(x,y, linestyle='steps')
- 線寬
inewidth或lw引數
x = np.linspace(-1, 1 ,1000)
y = (1-x**2)**0.5
plt.plot(x,y, linewidth=2)
- 點型
marker引數
x = np.linspace(-1, 1 ,20)
y = (1-x**2)**0.5
plt.figure(figsize=(12,9))
plt.plot(x,y, linewidth=2, marker='2', markersize=20)
- 多引數連用
x = np.linspace(0, 5, 10)
plt.plot(x,3*x,'r-.')
plt.plot(x, x**2, 'b^:') # blue line with dots
plt.plot(x, x**3, 'go-.') # green dashed line
plt.show()
-
更多點和線的設定
y = np.arange(1, 3, 0.3)
plt.plot(y, color='blue',
linestyle='dashdot',
linewidth=4, marker='o',
markerfacecolor='red',
markeredgecolor='black',
markeredgewidth=3,
markersize=12);
plt.show()
3.2 X、Y軸座標刻度
- xticks()和yticks()方法
x = [5, 3, 7, 2, 4, 1]
plt.plot(x);
plt.xticks(range(len(x)), ['a', 'b', 'c', 'd', 'e', 'f']); # 傳入位置和標籤引數,以修改座標軸刻度
plt.yticks(range(1, 8, 2));
plt.show()
- 物件導向方法
set_xticks、set_yticks、set_xticklabels、set_yticklabels方法
fig = plt.figure(figsize=(10, 4))
ax = fig.add_subplot(111)
x = np.linspace(0, 5, 100)
ax.plot(x, x**2, x, x**3, lw=2)
ax.set_xticks([1, 2, 3, 4, 5])
ax.set_xticklabels(['a','b','c','d','e'], fontsize=18)
yticks = [0, 50, 100, 150]
ax.set_yticks(yticks)
ax.set_yticklabels([y for y in yticks], fontsize=18); # use LaTeX formatted labels
- 正弦餘弦:LaTex語法,用等表示式在圖表上寫上希臘字母
x = np.arange(-np.pi,np.pi,0.01)
plt.figure(figsize=(12,9))
plt.plot(x,np.sin(x),x,np.cos(x))
plt.axis([x.min()-1,x.max()+1,-1.2,1.2])
#xticks:引數一刻度,引數二,對應刻度上的值
plt.xticks(np.arange(-np.pi,np.pi+1,np.pi/2),
['$-\delta$','$-\pi$/2','0','$\pi$/2','$\pi$'],size = 20)
plt.yticks([-1,0,1],['min','0','max'],size = 20)
plt.show()
四.2D圖形
4.1 直方圖
【直方圖的引數只有一個x!!!不像條形圖需要傳入x,y】
hist()的引數
bins
可以是一個bin數量的整數值,也可以是表示bin的一個序列。預設值為10
normed
如果值為True,直方圖的值將進行歸一化處理,形成概率密度,預設值為False
color
指定直方圖的顏色。可以是單一顏色值或顏色的序列。如果指定了多個資料集合,顏色序列將會設定為相同的順序。如果未指定,將會使用一個預設的線條顏色
orientation
通過設定orientation為horizontal建立水平直方圖。預設值為vertical
x = np.random.randint(5,size = 5)
display(x)
plt.hist(x,histtype = 'bar'); # 預設繪製10個bin
plt.show()
- 普通直方圖/累計直方圖
n = np.random.randn(10000)
fig,axes = plt.subplots(1,2,figsize = (12,4))
axes[0].hist(n,bins = 50)#普通直方圖
axes[0].set_title('Default histogram')
axes[0].set_xlim(min(n),max(n))
axes[1].hist(n,bins = 50,cumulative = True)# 累計直方圖
axes[1].set_title('Cumulative detailed histogram')
axes[1].set_xlim(min(n),max(n))
- 正太分佈
u = 100 #數學期望
s = 15 #方差
x = np.random.normal(u,s,1000) # 生成正太分佈資料
ax = plt.gca() #獲取當前圖表
ax.set_xlabel('Value')
ax.set_ylabel('Frequency') #設定x,y軸標題
ax.set_title("Histogram normal u = 100 s = 15") #設定圖表標題
ax.hist(x,bins = 100,color = 'r',orientation='horizontal')
plt.show()
4.2 條形圖
- bar
# 第一個引數為條形左下角的x軸座標,第二個引數為條形的高度;
# width引數設定條形寬度;color引數設定條形顏色;bottom引數設定條形底部的垂直座標
plt.bar([1, 2, 3], [3, 2, 5], width=0.5, color='r', bottom=1);
plt.ylim([0, 7])
plt.show()
# 例子:繪製並列條形圖
data1 = 10*np.random.rand(5)
data2 = 10*np.random.rand(5)
data3 = 10*np.random.rand(5)
locs = np.arange(1, len(data1)+1)
width = 0.27
plt.bar(locs, data1, width=width);
plt.bar(locs+width, data2, width=width, color='red');
plt.bar(locs+2*width, data3, width=width, color='green') ;
plt.xticks(locs + width*1, locs);
plt.show()
- barh
plt.barh([1, 2, 3], [3, 2, 5],height = 0.27,color = 'cyan');
plt.show()
4.3 餅圖
pie()
餅圖適合展示各部分佔總體的比例,條形圖適合比較各部分的大小
plt.figure(figsize = (4,4)) # 餅圖繪製正方形
x = [45,35,20] #百分比
labels = ['Cats','Dogs','Fishes'] #每個區域名稱
plt.pie(x,labels = labels)
plt.show()
plt.figure(figsize=(4, 4));
x = [0.1, 0.2, 0.3] # 當各部分之和小於1時,則不計算各部分佔總體的比例,餅的大小是數值和1之比
labels = ['Cats', 'Dogs', 'Fishes']
plt.pie(x, labels=labels); # labels引數可以設定各區域標籤
plt.show()
# labels引數設定每一塊的標籤;labeldistance引數設定標籤距離圓心的距離(比例值)
# autopct引數設定比例值的顯示格式(%1.1f%%);pctdistance引數設定比例值文字距離圓心的距離
# explode引數設定每一塊頂點距圓形的長度(比例值);colors引數設定每一塊的顏色;
# shadow引數為布林值,設定是否繪製陰影
plt.figure(figsize=(4, 4));
x = [4, 9, 21, 55, 30, 18]
labels = ['Swiss', 'Austria', 'Spain', 'Italy', 'France', 'Benelux']
explode = [0.2, 0.1, 0, 0, 0.1, 0]
colors = ['r', 'k', 'b', 'm', 'c', 'g']
plt.pie(x,
labels=labels,
labeldistance=1.2,
explode=explode,
colors=colors,
autopct='%1.1f%%',
pctdistance=0.5,
shadow=True);
plt.show()
# 繪製一個正方形的figure and axes
plt.figure(1, figsize=(4, 4))
# 圓弧按照逆時針繪製
labels = 'Spring', 'Summer', 'Autumn', 'Winter'
values = [15, 16, 16, 28]
explode =[0.1, 0.1, 0.1, 0.1] # 指定分裂序列,每一個元素表示每個圓弧間的偏移量,為半徑的百分比
# 繪製餅圖
plt.pie(values,
explode=explode,
labels=labels,
autopct='%1.1f%%', # 格式化繪製圓弧中的標籤,標籤可以是一個格式化字串或者一個可呼叫的物件(函式)
startangle=90) # 指定圓弧開始繪製的角度,預設從角度0(x軸)開始繪製
plt.title('Rainy days by season');
4.4 散點圖
【散點圖需要兩個引數x,y,但此時x不是表示x軸的刻度,而是每個點的橫座標!】
scatter()
# s引數設定散點的大小;c引數設定散點的顏色;marker引數設定散點的形狀
x = np.random.randn(1000)
y = np.random.randn(1000)
size = 50*abs(np.random.randn(1000))
colors = np.random.randint(16777215,size = 1000)
li = []
for color in colors:
a = hex(color)
str1 = a[2:]
l = len(str1)
for i in range(1,7-l):
str1 = '0'+str1
str1 = "#" + str1
li.append(str1)
plt.scatter(x, y,s = size, c=li, marker='d');
plt.show()
五.圖形內的文字、註釋、箭頭
5.1 文字
x = np.arange(0, 7, .01)
y = np.sin(x)
plt.plot(x, y);
plt.text(0.1, -0.04, 'sin(0)=0'); # 位置引數是座標
plt.show()
5.2 註釋
# 生成3個正態分佈資料資料集
x1 = np.random.normal(30, 3, 100)
x2 = np.random.normal(20, 2, 100)
x3 = np.random.normal(10, 3, 100)
# 繪製3個資料集,併為每個plot指定一個字串標籤
plt.plot(x1, label='plot') # 如果不想在圖例中顯示標籤,可以將標籤設定為_nolegend_
plt.plot(x2, label='2nd plot')
plt.plot(x3, label='last plot')
# 繪製圖例
plt.legend(bbox_to_anchor=(0, 1.02, 1, 0.102), # 指定邊界框起始位置為(0, 1.02),並設定寬度為1,高度為0.102
ncol=3, # 設定列數為3,預設值為1
mode="expand", # mode為None或者expand,當為expand時,圖例框會擴充套件至整個座標軸區域
borderaxespad=0.) # 指定座標軸和圖例邊界之間的間距
# 繪製註解
plt.annotate("Important value", # 註解文字的內容
xy=(55,20), # 箭頭終點所在位置
xytext=(5, 38), # 註解文字的起始位置,箭頭由xytext指向xy座標位置
arrowprops=dict(arrowstyle='->')); # arrowprops字典定義箭頭屬性,此處用arrowstyle定義箭頭風格
5.3 箭頭
六.3D圖
6.1 導包
import numpy as np
import matplotlib.pyplot as plt
#3d圖形必須的
from mpl_toolkits.mplot3d.axes3d import Axes3D
%matplotlib inline
6.2 生成資料
#係數,由X,Y生成Z
a = 0.7
b = np.pi
#計算Z軸的值
def mk_Z(X, Y):
return 2 + a - 2 * np.cos(X) * np.cos(Y) - a * np.cos(b - 2*X)
#生成X,Y,Z
x = np.linspace(0, 2*np.pi, 100)
y = np.linspace(0, 2*np.pi, 100)
X,Y = np.meshgrid(x, y)
Z = mk_Z(X, Y)
6.3 繪製圖形
fig = plt.figure(figsize=(14,6))
#建立3d的檢視,使用屬性projection
ax = fig.add_subplot(1, 2, 1, projection='3d')
ax.plot_surface(X,Y,Z,rstride = 5,cstride = 5)
#建立3d檢視,使用colorbar,新增顏色柱
ax = fig.add_subplot(1, 2, 2, projection='3d')
p = ax.plot_surface(X, Y, Z, cmap='rainbow', antialiased=True)
cb = fig.colorbar(p, shrink=0.5)