python3 matplotlib多個子圖對應同一個colorbar

python3 matplotlib多個子圖對應同一個colorbar

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 12 19:31:07 2019

@author: BAI Depei
"""
from osgeo import gdal
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize

#-------------------------讀取2007、2008、2009年TRMM降水遙感圖像-----------------------
path = 'E:\\課程PPT\\Python空間數據處理\\python空間數據處理-期中大作業02\\衛星降雨數據TRMM3B43_分辨率0.25度\\'
#有時候路徑必須雙反斜槓
dataset = gdal.Open(path + '3B43_2007.TIF')
dataset2 = gdal.Open(path + '3B43_2008.TIF')
dataset3 = gdal.Open(path + '3B43_2009.TIF')
samples = dataset.RasterXSize
lines = dataset.RasterYSize
bands = dataset.RasterCount
img_geotrans = dataset.GetGeoTransform()
#Out[10]: (-180.0, 0.25, 0.0, 50.0, 0.0, -0.25)
img_proj = dataset.GetProjection()
#Out[12]: 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"...]]]
#可以看到此遙感圖像未進行投影定義,因此還不是投影座標,只是地理座標
#在求解這些實測站點位於圖像中哪個行列位置時不用將其轉爲投影座標
im_data1 = dataset.ReadAsArray(0,0,samples,lines)
im_data2 = dataset2.ReadAsArray(0,0,samples,lines)
im_data3 = dataset3.ReadAsArray(0,0,samples,lines)
del dataset
del dataset2
del dataset3
#-------------------------------找到研究區範圍的行列號-------------------------------------
#-----------------------轉換左上、右下經緯度座標到對應遙感圖像上的行列號----------
im_loc = [[],[]]
#第一個列表放行號,存緯度換出來的值,後者爲列號,存經度換出來的值
# variable += [value] 等同於 variable.append(value)
#左上角 115 25.5
#右下角 117 27.5
pnt_coordinates = [[115,117],[27.5,25.5]]

for i in range(len(pnt_coordinates[0])):
    sample = sp.Symbol('sample')
    line = sp.Symbol('line')
    #pnt_coordinates[0][i] = img_geotrans[0] + sample*img_geotrans[1] + line*img_geotrans[2]
    #pnt_coordinates[1][i] = img_geotrans[3] + sample*img_geotrans[4] + line*img_geotrans[5]
    a = -pnt_coordinates[0][i] + img_geotrans[0] + sample*img_geotrans[1] + line*img_geotrans[2]
    b = -pnt_coordinates[1][i] + img_geotrans[3] + sample*img_geotrans[4] + line*img_geotrans[5]
    answer = sp.solve([a,b],[sample,line])#解二元一次方程組
    #Out[15]: {x: 0, y: 1}
    line = int(np.floor(answer[line]))
    sample = int(np.floor(answer[sample]))
    im_loc[0] += [line]
    im_loc[1] += [sample]
#--------------------------------校正數據---------------------------------------
cor_data1 = 0.797 * im_data1 + 352.279
cor_data2 = 0.797 * im_data2 + 352.279
cor_data3 = 0.797 * im_data3 + 352.279
#------------------------------起始終止行列號------------------------------------
start_line = im_loc[0][0]
end_line = im_loc[0][1]
start_sample = im_loc[1][0]
end_sample = im_loc[1][1]
#------------------------------裁剪圖像-----------------------------------------
data1 = im_data1[start_line:end_line,start_sample:end_sample]
data2 = im_data2[start_line:end_line,start_sample:end_sample]
data3 = im_data3[start_line:end_line,start_sample:end_sample]
cdata1 = cor_data1[start_line:end_line,start_sample:end_sample]
cdata2 = cor_data2[start_line:end_line,start_sample:end_sample]
cdata3 = cor_data3[start_line:end_line,start_sample:end_sample]
#----------------------------用於生產colorbar的vmin和vmax-----------------------
#求最小值
mins = []
mins.append(np.min(data1))
mins.append(np.min(data2))
mins.append(np.min(data3))
mins.append(np.min(cdata1))
mins.append(np.min(cdata2))
mins.append(np.min(cdata3))
vmin = np.min(mins)
#求最大值
maxes = []
maxes.append(np.max(data1))
maxes.append(np.max(data2))
maxes.append(np.max(data3))
maxes.append(np.max(cdata1))
maxes.append(np.max(cdata2))
maxes.append(np.max(cdata3))
vmax = np.max(maxes)
#fig,((ax0,ax1),(ax2,ax3),(ax4,ax5)) = plt.subplots(nrows = 3, ncols = 2,figsize = (18,12))
#------------------------------------繪圖---------------------------------------
fig,axs = plt.subplots(nrows = 2, ncols = 3,figsize = (12,8))
#figsize = (width,hight)
extent = (0,1,0,1)
#將x周和y軸都歸一化。方便指定label的位置(0,1)相對比例,否則指定label位置時不好指定
norm = Normalize(vmin = vmin,vmax = vmax)
#Normalize()跟歸一化沒有任何關係,函數的作用是將顏色映射到vmin-vmax上,即讓接下來的顏色表/顏色柱的起始和終止分別取值vmin和vmax
#axs[0,0].imshow(data1,extent = extent,vmin = vmin,vmax = vmax,cmap = 'jet_r')
axs[0,0].imshow(data1,extent = extent,norm = norm,cmap = 'jet_r')
axs[0,0].set_xlabel('2007 Original',fontdict = {'family' : 'Times New Roman','fontweight':'bold'})
axs[0,0].set_xticks(np.linspace(0,1,5))
font = {'fontweight':'bold'}
axs[0,0].set_xticklabels(('115.0E','115.5E','116.0E','116.5E','117.0E'),fontdict = font)
axs[0,0].set_yticks(np.linspace(0,1,5))
axs[0,0].set_yticklabels(('25.5 N','26.0 N','26.5 N','27.0 N','27.5 N'))
axs[0,1].imshow(data2,vmin = vmin,vmax = vmax,cmap = 'jet_r')
axs[0,1].set_xlabel('2008 Original',fontdict = {'family' : 'Times New Roman'})
axs[0,2].imshow(data3,vmin = vmin,vmax = vmax,cmap = 'jet_r')
axs[0,2].set_xlabel('2009 Original',fontdict = {'family' : 'Times New Roman'})
axs[1,0].imshow(cdata1,vmin = vmin,vmax = vmax,cmap = 'jet_r')
axs[1,0].set_xlabel('2007 Corrected',fontdict = {'family' : 'Times New Roman'})
axs[1,1].imshow(cdata2,vmin = vmin,vmax = vmax,cmap = 'jet_r')
axs[1,1].set_xlabel('2008 Corrected',fontdict = {'family' : 'Times New Roman'})
sc = axs[1,2].imshow(cdata3,vmin = vmin,vmax = vmax,cmap = 'jet_r')
axs[1,2].set_xlabel('2009 Corrected',fontdict = {'family' : 'Times New Roman'})
#norm = plt.colors.Normalize(vmin=vmin, vmax=vmax)
#前面三個子圖的總寬度 爲 全部寬度的 0.9;剩下的0.1用來放置colorbar
fig.subplots_adjust(right=0.9)
#colorbar 左 下 寬 高 
l = 0.92
b = 0.53
w = 0.015
h = 0.35
#對應 l,b,w,h;設置colorbar位置;
rect = [l,b,w,h] 
cbar_ax = fig.add_axes(rect) 
plt.colorbar(sc, cax=cbar_ax)
plt.savefig('correct_pictures.png',dpi = 300,bbox_inches='tight')
plt.show()

在這裏插入圖片描述
參考文獻:
[1]https://blog.csdn.net/weixin_43718675/article/details/102639611
[2]https://url.cn/5PjZ9df


版權歸作者 小白是哪個小白_ 所有,轉載、引用請註明鏈接出處。

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