设计个gui程序,第一栏为选取NC数据文件,第二栏为填写绘图时间,后面添加时间填写提示,例如2025042008,这个时间为北京时08时,但是NC文件数据为世界时。第三栏为填写经纬度范围,也添加提示,列入08-120,10-40.第4栏为填写多少高度层,列入500 200 850 700等。第五栏为选取是否标注本场位置。
第六个为点击生成图片,下面大框框为显示生成的图,并存在一个保存图片的按键。生成图代码如下import xarray as xr
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import cmaps
import matplotlib.dates as mdates
import datetime
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.mpl.ticker as cticker
from cartopy.io.shapereader import Reader
import matplotlib.patches as patches
import matplotlib.font_manager as fm
import warnings
from scipy.ndimage import gaussian_filter
import threading
import time
import random
import os
# ============== 解决中文乱码的关键设置 ==============
# 设置全局字体为支持中文的字体
plt.rcParams['font.family'] = 'SimHei' # 使用黑体,或者选择其他中文字体如'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 或者使用字体管理器指定具体字体文件路径
# font_path = 'path/to/your/chinese_font.ttf' # 如'C:/Windows/Fonts/simhei.ttf'
# font_prop = fm.FontProperties(fname=font_path)
# 然后在每个需要中文的地方添加fontproperties=font_prop参数
# =================================================
china_outline = cfeature.ShapelyFeature(
Reader(r'./china_shp/country.shp').geometries(), ##china_shp和程序在一个文件夹里
ccrs.PlateCarree(),
edgecolor='k',
facecolor='none',
)
yunnan = cfeature.ShapelyFeature(
Reader(r'./yunnan/yunnan.shp').geometries(),
ccrs.PlateCarree(),
edgecolor='k',
facecolor='none',
)
def draw_500hPa(ax, z, t, u, v, lat, lon, title, lon1, lon2, lat1, lat2, lon_span, lat_span):
ax.set_extent([lon1, lon2, lat1, lat2], crs=ccrs.PlateCarree())
ax.add_feature(china_outline, linewidth=1.5, zorder=2)
ax.add_feature(yunnan, linewidth=3.0, zorder=2)
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=1.0, zorder=1)
ax.add_feature(cfeature.OCEAN, facecolor='white', zorder=1)
ax.add_feature(cfeature.LAKES, linewidth=0.5, zorder=7, edgecolor='k', facecolor='none')
ax.set_xticks(np.arange(lon1, lon2 + lon_span * .1, lon_span), crs=ccrs.PlateCarree())
for label in ax.get_xticklabels():
label.set_horizontalalignment('left')
ax.set_yticks(np.arange(lat1, lat2 + lat_span * .1, lat_span), crs=ccrs.PlateCarree())
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
# 设置标题使用中文字体
ax.set_title(f'{title}', fontsize=30, loc='left') # 全局设置后自动生效
ax.tick_params(axis='both', labelsize=25)
###---------画温度等值线----------------
t_min = np.floor(t.min() / 4) * 4 # 向下取整到最近的4的倍数
t_max = np.ceil(t.max() / 4) * 4 # 向上取整到最近的4的倍数
levels_t = np.arange(t_min, t_max + 4, 4) # 创建以4为间隔的等值线数组
c_tem = ax.contour(
lon,
lat,
t,
levels=levels_t, # 指定等值线间隔为4
colors='red',
zorder=3,
linestyles='dashed',
linewidths=1.5
)
plt.clabel(c_tem, inline=True, fontsize=22, fmt='%1.0f') # 添加等值线标签
#
# c_tem = ax.contour(
# lon,
# lat,
# t,
# colors='red',
# zorder=3,
# linestyles='dashed',
# linewidths=1.5
# )
# plt.clabel(c_tem, inline=True, fontsize=22, fmt='%1.0f') # 添加等值线标签
##---------------绘制风羽------------------
uvb = ax.barbs(lon[::8], lat[::8], u[::8, ::8], v[::8, ::8],
flagcolor='k', barbcolor=['k', 'k'],
barb_increments=dict(half=2, full=4, flag=20),
length=6, linewidth=1.0,
transform=ccrs.PlateCarree(),
zorder=2)
z = gaussian_filter(z, 2.5) ##igma=0.3*((ksize-1)*0.5-1)+0.8,其中ksize为窗口大小,9点平滑(3*3,ksize=3)大概是0.8左右
##--------------画位势高度等值线-------------
z = gaussian_filter(z, 2.5)
levels = np.arange(100, 1000, 4)
c_gpt = ax.contour(
lon[::3],
lat[::3],
z[::3, ::3],
colors='blue',
zorder=3,
levels=levels[levels != 588],
linewidths=1.2
)
plt.clabel(c_gpt, inline=True, zorder=8, fontsize=22,
fmt='%1.0f') # 添加等值线标签
##--------------加粗588线-------------
c_g588 = ax.contour(
lon,
lat,
z,
colors='blue',
zorder=3,
levels=[588],
linewidths=3.0
)
plt.clabel(c_g588, inline=True, fontsize=22, fmt='%1.0f') # 添加等值线标签
# ================ 添加红色五角星标记 =================
star_lon = 100.7625
star_lat = 21.973611
ax.plot(star_lon, star_lat,
marker='*', markersize=15, color='red',
transform=ccrs.PlateCarree(), zorder=10)
# ===================================================
return ax
data_all = ['2025-04-20T00', '2025-04-20T09', '2025-04-20T12'] # 这里改成你需要的时间
def dr(data_all):
for datec in data_all:
figname = f'./{datec}_500hPa.png'
#####--------------------读取需要的数据-----------------------------
f = xr.open_dataset('G:\\sy\\ouzhou\\2025.4.20.nc')
# print(f.keys())
lon1, lon2, lat1, lat2 = [85, 120, 15, 35]
####---------------------提取500hPa数据画图-------------
lon1, lon2, lat1, lat2 = [40, 150, 10, 80]
lon_span, lat_span = [10, 10]
p_levelc = 500
z = f['z'].sel(valid_time=f'{datec}', pressure_level=p_levelc, latitude=slice(lat2, lat1),
longitude=slice(lon1, lon2)).sortby('latitude')
z /= 9.80665
z /= 10
# print(z)
u = f['u'].sel(valid_time=f'{datec}', pressure_level=p_levelc, latitude=slice(lat2, lat1),
longitude=slice(lon1, lon2)).sortby('latitude')
v = f['v'].sel(valid_time=f'{datec}', pressure_level=p_levelc, latitude=slice(lat2, lat1),
longitude=slice(lon1, lon2)).sortby('latitude')
t = f['t'].sel(valid_time=f'{datec}', pressure_level=p_levelc, latitude=slice(lat2, lat1),
longitude=slice(lon1, lon2)).sortby('latitude')
t -= 273.15
lat = f['latitude'].sel(latitude=slice(lat2, lat1)).sortby('latitude')
lon = f['longitude'].sel(longitude=slice(lon1, lon2))
time = int(datec[-2:]) + 8
title_c = f"{p_levelc}hPa {datec[:-3] +'北京时:'+ str(time) + '时'}"
fig = plt.figure(figsize=(20, 15), dpi=300) # 将figure创建移到循环内部
ax = fig.add_axes([0.1, 0.05, 0.7, 0.7], projection=ccrs.PlateCarree())
ax = draw_500hPa(ax, z, t, u, v, lat, lon, title_c, lon1, lon2, lat1, lat2, lon_span, lat_span)
print(figname)
plt.savefig(f'{figname}', bbox_inches='tight')
plt.close(fig) # 关闭图形释放内存
threads = []
for i in range(1):
t = threading.Thread(target=dr, args=(data_all,)) # 修正线程参数传递
threads.append(t)
t.start()
# 等待所有线程完成
for thread in threads:
thread.join()
最新发布