Matplotlib contourf contour画图实例(包含高斯滤波)
最近被要求复现图片

要求做到海面区域,完全一致。因为对于matplotlib使用不够熟练导致我在复现过程中遇到了好几个问题。
使用地图投影并不能达到图片所示效果
无论我使用使用地图投影,或者使用PlateCarree还是Lambert投影,都不能达到图片中的效果,最后我使用了PlateCarree投影,并在图片生成后对图片进行拉伸,才接近图片效果。
colorbar不能完全复现
我用了matplotlib自带的colormap但是不能达到图片效果,我也想过用matplotlib自带的生成渐变colormap的函数,但是效果也很差,最后我想了一个笨办法,就是一个一个颜色地读取然后自己创建一个色卡,我用到了苹果自带的功能,应该很多软件都有类似功能。使用读取出来的sRGB即可。


然后就解决了色卡的问题
contour曲线过于粗糙

我也尝试了很多方法,比如说每隔4个点读取数据,或者用线性插值等插值方法,将数据插值到更大的网格上去,但是收效甚微,最后发现可以使用高斯滤波的函数。下面直接放上成果图,因为我不会ps所以图片还是相差很多,如果有兄弟有更好的完善方法,可以dd我。

滤波函数使用方法:
from scipy.ndimage.filters import gaussian_filter
Arr_z = gaussian_filter(Arr_z, 1) # 高斯滤波
这是具体的高斯滤波:(21条消息) gaussian_filter( )函数(高斯滤波)_方如一的博客-CSDN博客
https://blog.csdn.net/Fwuyi/article/details/123585403
我把代码放在最后,import中可能很多都没有调用到,是我之前放的,懒得改了。
# 数据处理部分
import numpy as np
from numpy.linalg import solve # 用来解方程
import pandas as pd
import xarray as xr
import datetime as dt
import scipy
from scipy.io import loadmat # 读取m文件
from scipy.stats import linregress # 进行回归分析
from sklearn import linear_model
clf = linear_model.LinearRegression()
# import cfgrib
from scipy.optimize import curve_fit
from eofs.standard import Eof
import datetime as dt
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from matplotlib import colors
import matplotlib as mpl
import matplotlib.patches as mpatchesimport
import matplotlib.transforms as mtransformsdef
plt.rcParams['axes.unicode_minus'] =False # 打开负号
plt.rcParams['font.sans-serif'] = 'SimHei' # 显示中文
import cartopy.mpl.ticker as cticker
import scipy.ndimage
from scipy.ndimage.filters import gaussian_filter
#数据处理部分
dataset = xr.open_dataset('ETOPO_2022_v1_60s_N90W180_bed.nc')
print(dataset)
print()
z = dataset.z.loc[36.27:42.3, 117.11:122.46][::4, ::4]
print(z.lon.shape, z.lat.shape)
print(np.array(z.lon.shape)[0])
lon = np.array(z.lon).reshape(np.array(z.lon.shape)[0], 1)
lat = np.array(z.lat).reshape(np.array(z.lat.shape)[0], 1)
Arr_z = np.array(z)
# Arr_z = gaussian_filter(Arr_z, 1) # 高斯滤波
print(Arr_z.shape, lon.shape, lat.shape)
lon, lat = np.meshgrid(lon, lat)
print(Arr_z.min(), Arr_z.max())
#画图部分
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] =False # 打开负号
# 创建色卡
# plt.rcParams.update({'figure.dpi':150})
proj = ccrs.PlateCarree(central_longitude=0)
fig = plt.figure(figsize=(14.56, 18.74))
axes = fig.add_axes([0, 0, 1, 1], projection=proj)
axes.add_feature(cfeature.COASTLINE, zorder=2, linewidth=1.5)
axes.add_feature(cfeature.LAND, zorder=1)
leftlon, rightlon, lowerlat, upperlat = (117.11,122.46,36.27,42.3)
img_extent = [leftlon, rightlon, lowerlat, upperlat]
# 自定义色卡
cmap = mpl.cm.Blues_r
cmap1 = mpl.colors.ListedColormap(['#040A47', '#02165F', '#001651', '#042B61', '#063C88', '#1B76D7', '#207DD3', '#33ABED', '#4FBAF1', '#5EBEEB', '#81CEEA', '#97D5E9'])
bounds = [-65, -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, 0]
#040A47 02165F 001651 042B61 063C88 1B76D7 207DD3 33ABED 4FBAF1 5EBEEB 81CEEA 97D5E9
red_color_normal = mpl.colors.LinearSegmentedColormap.from_list('自定义的颜色名字', [(0, '#04023D'),(1, '#96CEE3')], N=256) # 颜色渐变
norm = mpl.colors.BoundaryNorm(bounds, cmap1.N) # 自定义色卡的归一化
vmax = 0
vmin = -60
axes.contourf(lon, lat, Arr_z, norm=norm,zorder=0, cmap=cmap1, levels=bounds, extend='both')
contour = axes.contour(lon, lat, Arr_z, zorder=0, colors='#95D6F9', linestyles="-", levels=bounds, extend='none')
plt.axis('off')