數據分析-使用matplotlib可視化工具畫圖

區域填充

以某種顏色填充兩條曲線的閉合區域.

mp.fill_between(
	x, 				# x值的區間
    sin_x, 			# 與x組成一條曲線
    cos_x, 			# 與x組成第二條曲線
    sin_x < cos_x,	# 繪製填充的條件
    color='',		
    alpha=0.5
)

案例: 繪製 sin_x=sin(x) cos_x=cos(x/2)/2 [0, 8π]

"""
demo01_fill.py   區域填充
"""
import numpy as np
import matplotlib.pyplot as mp

n = 1000
x = np.linspace(0, 8*np.pi, n)
sin_x = np.sin(x)
cos_x = np.cos(x/2) / 2 

mp.figure('Fill', facecolor='lightgray')
mp.title('Fill', fontsize=16)
mp.xlabel('X', fontsize=12)
mp.ylabel('Y', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(x, sin_x, color='dodgerblue',
	label=r'$y=sin(x)$')
mp.plot(x, cos_x, color='orangered',
	label=r'$y=\frac{1}{2}cos(\frac{x}{2})$')
mp.fill_between(
    x, sin_x, cos_x, 
    sin_x>cos_x,
	color='deepskyblue', alpha=0.6)
mp.fill_between(
    x, sin_x, cos_x, 
    sin_x<cos_x,
	color='orangered', alpha=0.6)
mp.legend()
mp.show()

條形圖(柱狀圖)

mp.bar(
    x, 			# 橫座標數組
    height, 	# 對應每個x的柱子的高度
    width,		# 對應每個x的柱子的寬度
    color='',   
    label='',
    alpha=0.2
)

案例:

"""
demo02_bar.py 柱狀圖
"""
import numpy as np
import matplotlib.pyplot as mp

x = np.arange(12)
apples=[98,12,37,65,18,94,56,23,49,56,24,56]
oranges=[75,20,39,65,23,65,10,23,94,76,89,12]

mp.figure('Bar Chart', facecolor='lightgray')
mp.title('Bar Chart', fontsize=16)
mp.xlabel('Month', fontsize=14)
mp.ylabel('Num', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.bar(x+0.2, apples, 0.4, color='limegreen',
	   label='Apples')
mp.bar(x-0.2, oranges, 0.4, color='orangered',
	   label='Oranges')
# 設置刻度
mp.xticks(x, ['Jan', 'Feb', 'Mar', 'Apr',
	'May', 'Jun', 'Jul', 'Aug', 'Sep',
	'Oct', 'Nov', 'Dec'])

mp.legend()
mp.show()

餅狀圖

mp.pie(
	values, 		# 扇形值列表
    spaces,			# 扇形之間間距列表
    labels,         # 扇形標籤文本列表
    colors,			# 扇形顏色列表
    '%.2f%%',		# 百分比的格式
    shadow=True,	# 陰影
    startangle=90,	# 餅狀圖的繪製起始角度
    radius=1		# 餅狀圖的半徑
)

案例:

"""
demo03_pie.py  餅狀圖
"""
import matplotlib.pyplot as mp

mp.figure('Languages', facecolor='lightgray')
mp.title('Languages', fontsize=18)

labels = ['Python', 'Javascript', 'C++', 
          'Java', 'PHP']
spaces = [0.05, 0.01, 0.01, 0.01, 0.01]
values = [26, 17, 21, 25, 5]
colors = ['dodgerblue', 'orangered', 
          'limegreen', 'violet', 'gold']

# 等軸比例繪製pie
mp.axis('equal')
mp.pie(values, spaces, labels, colors, 
	   '%.2f%%', shadow=True,
	   startangle=90)
mp.show()

等高線圖

等高線圖屬於3D數學模型, 需要整理網格點座標矩陣, 還需要得到每個點的高度值.

等高線相關API:

# 繪製等高線
cntr = mp.contour(
	x, y,	# x,y爲二維數組,組成網格點座標矩陣
    z, 		# 每個座標的高度值
    8,		# 把整體高度分爲8份
    colors='',	# 等高線的顏色
    linewidths=''	# 等高線的線寬
)
# cntr等高線對象繪製標註
mp.clabel(cntr, 
          inline_spacing=1, # 文本與線的間隔
          fmt='%.1f',fontsize=10) 
# 等高線填充顏色
mp.contourf(x, y, z, 8, cmap='jet')

案例:

"""
demo04_contour.py  等高線圖
"""
import numpy as np
import matplotlib.pyplot as mp

# 生成網格點座標矩陣
n = 1000
x, y = np.meshgrid(np.linspace(-3, 3, n),
				   np.linspace(-3, 3, n))
# 根據x,y 計算當前座標下的z高度值
z = (1-x/2 + x**5 + y**3) * np.exp(-x**2 -y**2)

mp.figure('Contour', facecolor='lightgray')
mp.title('Contour', fontsize=18)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
cntr = mp.contour(x, y, z, colors='black', 
		   linewidths=0.5)
# cntr等高線對象繪製標註
mp.clabel(cntr, inline_spacing=1, fmt='%.1f',
	      fontsize=10)
# 等高線填充顏色
mp.contourf(x, y, z, 8, cmap='jet')

mp.show()

熱成像圖

# 以jet映射顯示z矩陣的圖像值
# origin: y座標軸方向
#  lower: 較小的數字在下方
#  upper: 較小的數字在上方
mp.imshow(z, cmap='jet', origin='lower')

案例:

"""
demo05_imshow.py  熱成像圖
"""
import numpy as np
import matplotlib.pyplot as mp

# 生成網格點座標矩陣
n = 1000
x, y = np.meshgrid(np.linspace(-3, 3, n),
				   np.linspace(-3, 3, n))
# 根據x,y 計算當前座標下的z高度值
z = (1-x/2 + x**5 + y**3) * np.exp(-x**2 -y**2)

mp.figure('Imshow', facecolor='lightgray')
mp.title('Imshow', fontsize=18)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.imshow(z, cmap='jet', origin='lower')
mp.show()

極座標系

當需要處理角度相關的函數圖像時, 可能需要使用極座標系繪製圖像.

mp.gca(projection='polar')
mp.plot()

案例: r = 0.6 * t θ 關於 ρ 的函數

"""
demo06_polar.py  極座標系
"""
import numpy as np
import matplotlib.pyplot as mp

x = np.linspace(0, 8*np.pi, 1000)
y = 0.6 * x

mp.figure('Polar', facecolor='lightgray')
mp.title('Polar', fontsize=16)
mp.grid(linestyle=':')
mp.gca(projection='polar')
mp.plot(x, y, color='dodgerblue')
mp.show()

3D圖像的繪製

matplotlib支持繪製三維線框圖, 三維曲面圖, 三維散點圖. 需要使用axes3d提供3d座標系.

from mpl_toolkits.mplot3d import axes3d
ax3d = mp.gca(projection='3d')

ax3d.plot_wireframe()	# 繪製3d線框圖
ax3d.plot_surface()		# 繪製3d曲面圖
ax3d.scatter()			# 繪製3d散點圖

三維線框圖

ax3d.plot_wireframe(
    x, y, 	# x,y網格點座標矩陣
    z, 		# z爲每個座標點的值
	rstride=30,	# 行跨距
    cstride=30, # 列跨距
    linewidth=1,
    color=''
)	

案例:

"""
demo06_wireframe.py  三維線框圖
"""
import numpy as np
import matplotlib.pyplot as mp
from mpl_toolkits.mplot3d import axes3d

# 生成網格點座標矩陣
n = 1000
x, y = np.meshgrid(np.linspace(-3, 3, n),
				   np.linspace(-3, 3, n))
# 根據x,y 計算當前座標下的z高度值
z = (1-x/2 + x**5 + y**3) * np.exp(-x**2 -y**2)

mp.figure('Wireframe', facecolor='lightgray')
ax3d = mp.gca(projection='3d')
ax3d.set_xlabel('X', fontsize=14)
ax3d.set_ylabel('Y', fontsize=14)
ax3d.set_zlabel('Z', fontsize=14)
ax3d.plot_wireframe(x, y, z, rstride=10, 
	cstride=10,color='dodgerblue')
mp.show()

三維曲面圖

ax3d.plot_surface(
    x, y, 	# x,y網格點座標矩陣
    z, 		# z爲每個座標點的值
	rstride=30,	# 行跨距
    cstride=30, # 列跨距
    cmap='jet'
)	

三維散點圖

ax3d.scatter(
	x, y, z,  		 # x,y,z  確定一組散點座標
    marker='',		 # 點型
    s = 60,			 # 點的大小
    edgecolor='',	 # 邊緣色
    facecolor='',	 # 填充色
    zorder=3,		 # 繪製圖層編號 
    c=d,			 # 設置過渡性顏色
    cmap='jet'		 # 顏色映射
)

簡單動畫

動畫即是在一段時間內快速連續的重新繪製圖像的過程.

matplotlib提供了方法用於處理簡單動畫的繪製:

import matplotlib.animation as ma
def update(number):
    pass

# 每隔30毫秒,執行一次update
ma.FuncAnimation(
    mp.gcf(),   # 作用域當前窗體
    update,     # 更新函數的函數名
    interval=30 # 每隔30毫秒,執行一次update
)  

案例: 隨機生成各種顏色的100個氣泡, 讓他們不斷增大.

  1. 隨機生成100個氣泡.
  2. 每個氣泡擁有四個屬性: position, size, growth, color
  3. 把每個氣泡繪製到窗口中.
  4. 開啓動畫,在update函數中更新每個氣泡的屬性並重新繪製
"""
demo11_bubble.py  簡單動畫
1. 隨機生成100個氣泡.
2. 每個氣泡擁有四個屬性: position, size, growth, color
3. 把每個氣泡繪製到窗口中.
4. 開啓動畫,在update函數中更新每個氣泡的屬性並重新繪製
"""
import numpy as np
import matplotlib.pyplot as mp
import matplotlib.animation as ma

n = 100
balls = np.zeros(n, dtype=[
		('position', float, 2), # 位置屬性
		('size', float, 1),     # 大小屬性
		('growth', float, 1),   # 生長速度
		('color', float, 4)])   # 顏色屬性
# 初始化每個泡泡
# uniform: 從0到1取隨機數,填充n行2列的數組
balls['position']=np.random.uniform(0,1,(n,2))
balls['size']=np.random.uniform(50,70,n)
balls['growth']=np.random.uniform(10,20,n)
balls['color']=np.random.uniform(0,1,(n,4))
# 繪製100個泡泡
mp.figure('Bubble', facecolor='lightgray')
mp.title('Bubble', fontsize=18)
mp.xticks([])
mp.yticks([])
sc = mp.scatter(balls['position'][:,0], 
	       balls['position'][:,1],
	       balls['size'], 
	       color=balls['color'])

# 啓動動畫
def update(number):
	balls['size'] += balls['growth']
	# 讓某個泡泡破裂,從頭開始執行
	boom_i = number % n
	balls[boom_i]['size'] = 60
	balls[boom_i]['position']= \
			np.random.uniform(0, 1, (1, 2))
	# 重新設置屬性
	sc.set_sizes(balls['size'])
	sc.set_offsets(balls['position'])

anim = ma.FuncAnimation(
	mp.gcf(), update, interval=30)

mp.show()

基於生成器函數提供數據, 實現動畫的繪製.

def update(data):
    pass

def generator():
    yield data 
    
# 每10毫秒執行生成器, 把結果交給update, 更新圖像
ma.FuncAnimation(
    mp.gcf(), 
    update, 	# 更新函數
    generator,  # 生成器函數
	interval=10
)

案例: 模擬心電圖. y = sin(2πt)*exp(sin(0.2πt))

"""
demo12_gen.py  模擬心電圖
"""
import numpy as np
import matplotlib.pyplot as mp
import matplotlib.animation as ma

mp.figure('Signal', facecolor='lightgray')
mp.title('Signal', fontsize=16)
mp.xlim(0, 10)
mp.ylim(-3, 3)
mp.grid(linestyle=':')
pl = mp.plot([],[], color='dodgerblue',
		label='Signal')[0]
# 啓動動畫
def update(data):
	t, v = data
	x, y = pl.get_data()  #x y: ndarray數組
	x = np.append(x, t)
	y = np.append(y, v)
	# 重新繪製圖像
	pl.set_data(x, y)
	# 移動座標軸
	if x[-1]>5:
		mp.xlim(x[-1]-5, x[-1]+5)


x = 0
def generator():
	global x
	y = np.sin(2 * np.pi * x) * \
		np.exp(np.sin(0.2 * np.pi * x))
	yield (x, y)
	x += 0.05

anim = ma.FuncAnimation(mp.gcf(), 
	update, generator, interval=30)
mp.show()

numpy常用函數

加載文件

dates, opening_prices = np.loadtxt(
	'../xxxx/aapl.csv',	# 文件路徑
    delimiter=',',		# 分隔符
    unpack=True,		# 是否拆包
    usecols=(1,3),		# 需要讀取哪些列
    dtype='U10, f8',	# 設置每列的數據類型
    converters={1:func} # 數據轉換器
)

案例:

"""
demo12_loadtxt.py  加載文件
"""
import numpy as np
import matplotlib.pyplot as mp
import datetime as dt
import matplotlib.dates as md

# 當numpy解析文本時,將會把第一列中的每個字符串
# 都傳給函數進行處理, 將處理完畢後的返回值
# 轉成需要的M8[D]類型
def dmy2ymd(dmy):
	dmy = str(dmy, encoding='utf-8')
	# 把dmy轉成日期對象
	d = dt.datetime.strptime(dmy, '%d-%m-%Y')
	t = d.date()
	s = t.strftime('%Y-%m-%d')
	return s

# 加載文件
dates, closing_prices = np.loadtxt(
	'../da_data/aapl.csv', delimiter=',', 
	usecols=(1,6), unpack=True, 
	dtype='M8[D], f8' , 
	converters={1:dmy2ymd})

# 繪製收盤價
mp.figure('AAPL', facecolor='lightgray')
mp.title('AAPL', fontsize=18)
mp.xlabel('Date', fontsize=14)
mp.ylabel('Price', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
# 設置主刻度定位器爲每週一
ax = mp.gca()
ax.xaxis.set_major_locator(
	md.WeekdayLocator(byweekday=md.MO))
ax.xaxis.set_major_formatter(
	md.DateFormatter('%Y/%m/%d'))

# 把M8[D]轉爲matplotlib識別的date類型
dates = dates.astype(md.datetime.datetime)
mp.plot(dates, closing_prices, 
	color='dodgerblue', linewidth=2,
	linestyle='--', label='closing_prices')
mp.legend()
# 自動格式化x軸的日期輸出
mp.gcf().autofmt_xdate()
mp.show()

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