利用Matplotlib實現(xiàn)單畫布繪制多個子圖
更新時間:2023年02月07日 08:50:11 作者:楊哥學(xué)編程
這篇文章主要介紹了利用Matplotlib實現(xiàn)單畫布繪制多個子圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
Matplotlib實現(xiàn)單畫布繪制多個子圖
最近研究Python數(shù)據(jù)分析,需要利用Matplotlib繪制圖表,并將多個圖表繪制在一張圖中,經(jīng)過一番折騰,利用matplotlib包下的subplot()
函數(shù)即可實現(xiàn)此功能。
代碼實現(xiàn):
import matplotlib.pyplot as plt import numpy as np class Graph(object): def __init__(self): self.font = { 'size': 13 } plt.figure(figsize=(9, 6)) plt.subplots_adjust(wspace=0.7, hspace=0.5) plt.rcParams['font.family'] = 'simhei' plt.rcParams['axes.unicode_minus'] = False def twinx(self): a1 = plt.subplot(231) plt.title('雙縱軸折線圖', fontdict=self.font) a1.plot(subjects, v1, label='v1') a1.set_ylabel('v1') a1.legend(loc='upper right', bbox_to_anchor=[-0.5, 0, 0.5, 1], fontsize=7) a2 = a1.twinx() a2.plot(subjects, v2, 'r--', label='v2') a2.set_ylabel('v2') a2.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7) def scatter(self): plt.subplot(232) plt.title('散點圖', fontdict=self.font) x = range(50) y_jiangsu = [np.random.uniform(15, 25) for i in x] y_beijing = [np.random.uniform(5, 18) for i in x] plt.scatter(x, y_beijing, label='v1') plt.scatter(x, y_jiangsu, label='v2') plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7) def hist(self): plt.subplot(233) plt.title('直方圖', fontdict=self.font) x = np.random.normal(size=100) plt.hist(x, bins=30) def bar_dj(self): plt.subplot(234) plt.title('堆積柱狀圖', fontdict=self.font) plt.bar(np.arange(len(v1)), v1, width=0.6, label='v1') for x, y in enumerate(v1): plt.text(x, y, y, va='top', ha='center') plt.bar(np.arange(len(v2)), v2, width=0.6, bottom=v1, label='v2') for x, y in enumerate(v2): plt.text(x, y + 60, y, va='bottom', ha='center') plt.ylim(0, 200) plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7) plt.xticks(np.arange(len(v1)), subjects) def bar_bl(self): plt.subplot(235) plt.title('并列柱狀圖', fontdict=self.font) plt.bar(np.arange(len(v1)), v1, width=0.4, color='tomato', label='v1') for x, y in enumerate(v1): plt.text(x - 0.2, y, y) plt.bar(np.arange(len(v2)) + 0.4, v2, width=0.4, color='steelblue', label='v2') for x, y in enumerate(v2): plt.text(x + 0.2, y, y) plt.ylim(0, 110) plt.xticks(np.arange(len(v1)), subjects) plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7) def barh(self): plt.subplot(236) plt.title('水平柱狀圖', fontdict=self.font) plt.barh(np.arange(len(v1)), v1, height=0.4, label='v1') plt.barh(np.arange(len(v2)) + 0.4, v2, height=0.4, label='v2') plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7) plt.yticks(np.arange(len(v1)), subjects) def main(): g = Graph() g.twinx() g.scatter() g.hist() g.bar_dj() g.bar_bl() g.barh() plt.savefig('坐標(biāo)軸類.png') plt.show() if __name__ == '__main__': subjects = ['語文', '數(shù)學(xué)', '英語', '物理', '化學(xué)'] v1 = [77, 92, 83, 74, 90] v2 = [63, 88, 99, 69, 66] main()
效果如下:
可以看到,一個畫板上放了6個子圖。達到了我們想要的效果。
現(xiàn)在來解析剛剛的部分代碼:
plt.figure(1)
:表示取第一塊畫板,一個畫板就是一張圖,如果你有多個畫板,那么最后就會彈出多張圖。plt.subplot(231)
:221表示將畫板劃分為2行3列,然后取第1個區(qū)域。那么第幾個區(qū)域是怎么界定的呢?這個規(guī)則遵循行優(yōu)先數(shù)數(shù)規(guī)則.優(yōu)先從行開始數(shù),從左到右按順序1234……然后再下一行。
Matplotlib繪制多個動態(tài)子圖
import os import cv2 import pytz import numpy as np from tqdm import tqdm import matplotlib.pyplot as plt from matplotlib import animation from matplotlib.gridspec import GridSpec from datetime import datetime # (200,125) ,(300,185) def ave_area(arrays, left_top=(350, 180), right_lower=(400,255)): np_array = arrays[left_top[0]:right_lower[0], left_top[1]:right_lower[1]].reshape(1, -1) delete_0 = np_array[np_array != 0] return np.mean(delete_0) / 1000 img_depths_x = [] img_depths_y = [] img_colors = [] dirs = r'Z:\10.1.22.215\2021-09-09-18' for file in tqdm(os.listdir(dirs)[4000:4400]): try: img_path = os.path.join(dirs, file) data = np.load(img_path, allow_pickle=True) depthPix, colorPix = data['depthPix'], data['colorPix'] #rgbimage = cv2.cvtColor(colorPix, cv2.COLOR_BGR2RGB) font = cv2.FONT_HERSHEY_SIMPLEX text = file.replace('.npz', '') cv2.putText(colorPix, text, (10, 30), font, 0.75, (0, 0, 255), 2) cv2.putText(depthPix, text, (10, 30), font, 0.75, (0, 0, 255), 2) #cv2.imshow('example', colorPix) cv2.waitKey(10) indexes = file.replace('.npz', '') key = datetime.strptime(indexes, '%Y-%m-%d-%H-%M-%S-%f').astimezone(pytz.timezone('Asia/ShangHai')).timestamp() #格式時間轉(zhuǎn)換 img_depths_x.append(key) img_depths_y.append(ave_area(depthPix)) img_colors.append(cv2.cvtColor(colorPix,cv2.COLOR_BGR2RGB)) except: continue fig = plt.figure(dpi=100, constrained_layout=True, # 類似于tight_layout,使得各子圖之間的距離自動調(diào)整【類似excel中行寬根據(jù)內(nèi)容自適應(yīng)】 figsize=(15, 12) ) gs = GridSpec(3, 1, figure=fig)#GridSpec將fiure分為3行3列,每行三個axes,gs為一個matplotlib.gridspec.GridSpec對象,可靈活的切片figure ax1 = fig.add_subplot(gs[0:2, 0]) ax2 = fig.add_subplot(gs[2:3, 0]) xdata, ydata = [], [] rect = plt.Rectangle((350, 180), 75, 50, fill=False, edgecolor = 'red',linewidth=1) ax1.add_patch(rect) ln1 = ax1.imshow(img_colors[0]) ln2, = ax2.plot([], [], lw=2) def init(): ax2.set_xlim(img_depths_x[0], img_depths_x[-1]) ax2.set_ylim(12, 14.5) return ln1, ln2 def update(n): ln1.set_array(img_colors[n]) xdata.append(img_depths_x[n]) ydata.append(img_depths_y[n]) ln2.set_data(xdata, ydata) return ln1, ln2 ani = animation.FuncAnimation(fig, update, frames=range(len(img_depths_x)), init_func=init, blit=True) ani.save('vis.gif', writer='imagemagick', fps=10)
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Pandas中DataFrame對象轉(zhuǎn)置(交換行列)
本文主要介紹了Pandas中DataFrame對象轉(zhuǎn)置(交換行列),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02詳解Python中@staticmethod和@classmethod區(qū)別及使用示例代碼
這篇文章主要介紹了詳解Python中@staticmethod和@classmethod區(qū)別及使用示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12