06-Matplotlib

weixin_33782386發表於2018-12-20

一.圖片灰度處理

導包
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)
14575314-9b14baff9e0257b3.png
jinzhengen.png
3種方法
# 1, 最大值法
jin_max = jin.max(axis=-1)
jin_max.shape
輸出:
(273, 411)

plt.imshow(jin_max, cmap='gray')
plt.axis('off')
14575314-5ca5c1ce891c9aae.png
最大值法灰度.png
# 作為對比,使用最小值
jin_min = jin.min(axis=-1)
plt.imshow(jin_min, cmap='gray')
14575314-d5c61e9860624d2e.png
最小值法灰度.png
# 2,平均值
jin_mean = jin.mean(axis=-1)
plt.imshow(jin_mean,cmap='gray')
14575314-9a3e7f7da832c94b.png
平均值法灰度.png
# 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')
14575314-b5d8298f9067b8dc.png
加權平均法灰度.png

二.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)
14575314-d24378d952bf8d39.png
一條曲線.png
  • 多條曲線
    1、可以使用多個plot函式(推薦),在一個圖中繪製多個曲線
x = np.linspace(-np.pi, np.pi, 100)
y = np.sin(x)
z = np.cos(x)
plt.plot(x, y)
14575314-a2011f1319a1d625.png
單條曲線.png

2、也可以在一個plot函式中傳入多對X,Y值,在一個圖中繪製多個曲線

plt.plot(x,y, x,z)
14575314-8d7472f31d2dc514.png
雙條曲線.png
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)
14575314-39aa2250ee795b9f.png
網格圖片.png

方法二

# 通過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)
14575314-f46fb3bdb2c9bafe.png
網格圖2.png
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()
14575314-52ee6f1c217e275e.png
axis未傳引數圖.png
plt.plot(x,y)
# 通過axis方法來設定座標軸的界限
plt.axis([-np.pi, np.pi, -1,1])
14575314-80adfeeee3c8b7b2.png
axis設定座標圖.png
plt.plot(x,y)
# tight是axis預設的樣式,緊緻的樣式
# plt.axis('tight')
# off關閉座標軸, 經常用在顯示圖片上.
# plt.axis('off')
# 設定equal, 把畫布的長寬設定成一樣大
plt.axis('equal') 
14575314-c38574f5a3c22668.png
axis設定equal圖.png

除了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)
14575314-3127d18a51f376fa.png
xlim和ylim設定圖.png
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))
14575314-53d8bd9a55741ec8.png
X軸標籤.png
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))
14575314-4e79ea72554cc95d.png
Y軸標籤.png
2.6 座標軸標題

title方法

plt.plot(x,y)
title = plt.title('這是一個正弦', fontdict=dict(fontsize=20), loc='right')
14575314-56bfec36e6e11148.png
座標軸標題.png
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()
14575314-7a5e177c3c152365.png
圖例1.png
# 第二種方法
# 不需要在建立圖形的時候寫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'])
14575314-1724c315298a2a88.png
圖例2.png
  • loc引數


    14575314-4e79fc0990c521ed.png
    loc.png
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)
14575314-6ff71a158792045b.png
loc圖.png
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)
14575314-6bc390c38f51f711.png
nloc圖.png
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)
14575314-57db79d0d2ac4ec3.png
儲存圖片.png

三.設定plot的風格和樣式

3.1 點和線的樣式
  • 顏色
    引數color或c


    14575314-26c735a8644bbbbd.png
    顏色.png
x = np.linspace(-10, 10, 1000)
plt.plot(x, np.sin(x), c='r')
14575314-9e68d10eedee918b.png
顏色r.png
  • 透明度
    alpha引數
x = np.linspace(-10, 10, 1000)
# 透明度一般0到1就夠了.
plt.plot(x, np.sin(x), c='r', alpha=0.8)
14575314-9cb3bc8f5a2b72ab.png
透明度.png
  • 背景色
    設定背景色,通過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)
14575314-54a87c6116532e79.png
背景色.png
  • 線型
    引數linestyle或ls


    14575314-9e6f6c811f5d3c39.png
    線型.png
x = np.linspace(-1, 1 ,1000)
y = (1-x**2)**0.5
plt.plot(x,y, linestyle='steps')
14575314-58c20ea5ab77723f.png
線型設定.png
  • 線寬
    inewidth或lw引數
x = np.linspace(-1, 1 ,1000)
y = (1-x**2)**0.5
plt.plot(x,y, linewidth=2)
14575314-097074f3a6412042.png
線寬.png
  • 點型
    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)
14575314-8cad96c8cc7f86e6.png
點型.png
  • 多引數連用
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()
14575314-1d4228025f36dd0d.png
多引數連用.png
  • 更多點和線的設定


    14575314-a9576a504f332f2a.png
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()
14575314-479b5a3e11cfadea.png
點線設定圖.png
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()
14575314-dc5d3c13f82d6e91.png
xticks.png
  • 物件導向方法
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
14575314-d2d120d42138a103.png
物件導向.png
  • 正弦餘弦: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() 
14575314-be39e21a0b44e751.png
正弦餘弦.png

四.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))
14575314-66b25c2cdb522ac9.png
直方圖.png
  • 正太分佈
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()
14575314-bb519e840c6d3dbb.png
正態分佈.png
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()
14575314-1e17588a2bc5394b.png
bar圖.png
# 例子:繪製並列條形圖

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()
14575314-95853ce56e6e9ada.png
bar1.png
  • barh
plt.barh([1, 2, 3], [3, 2, 5],height = 0.27,color = 'cyan');
plt.show()
14575314-a30171ed8a562e5e.png
barh.png
4.3 餅圖

pie()
餅圖適合展示各部分佔總體的比例,條形圖適合比較各部分的大小

plt.figure(figsize = (4,4)) # 餅圖繪製正方形
x = [45,35,20] #百分比
labels = ['Cats','Dogs','Fishes'] #每個區域名稱
plt.pie(x,labels = labels)
plt.show()
14575314-7d285223420df651.png
餅圖1.png
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()
14575314-86be645530138cfd.png
餅圖2.png
# 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()
14575314-f08f268e85aec237.png
餅圖3.png
# 繪製一個正方形的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');
14575314-a75aef1a64c344b6.png
餅圖4.png
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()
14575314-7b9dfc2edbd46bf0.png
散點圖.png

五.圖形內的文字、註釋、箭頭

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()
14575314-2955f235fb3c0b9e.png
文字.png
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定義箭頭風格
14575314-7890b155526fee22.png
註釋.png
5.3 箭頭
14575314-37aff418645ab6bc.png
箭頭.png

六.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)
14575314-c872863cec12192d.png
3D圖.png