zcahjl3/figmirror-code-aug10
0
1import matplotlib.pyplot as plt 2import numpy as np 3from matplotlib.collections import PolyCollection 4 5# 数据生成 6np.random.seed(42) 7time_step = np.linspace(0, 24, 60) 8pressure = 1010 + 25 * np.sin(np.pi * time_step / 6) + 0.5*np.random.normal(0, 5, 60) 9wind_speed = 7 + 3 * np.sin(np.pi * time_step / 12)**2 + np.cos(np.pi * time_step / 12) + 0.05*np.random.normal(0, 2, 60) 10 11# 6小时分组计算平均 12bins = np.arange(0, 25, 6) 13inds = np.digitize(time_step, bins) - 1 14group_p = [pressure[inds == i].mean() for i in range(len(bins)-1)] 15group_w = [wind_speed[inds == i].mean() for i in range(len(bins)-1)] 16group_centers = (bins[:-1] + bins[1:]) / 2 17 18fig, axes = plt.subplots(3, 1, figsize=(10, 15), constrained_layout=True) 19 20# 第1部分:分组平均并列柱状图 + 折线 21ax_a = axes[0] 22bar_width = 1.8 23ax_a.bar(group_centers - bar_width/2, group_p, width=bar_width, color="#b90b5f", alpha=0.7, label="Avg Pressure") 24ax_a.set_ylabel("Pressure (hPa)") 25ax_a2 = ax_a.twinx() 26ax_a2.plot(group_centers, group_w, "-o", color="#06a7a7", label="Avg Wind Speed") 27ax_a2.set_ylabel("Wind Speed (km/h)") 28ax_a.set_title("6-Hour Grouped Averages") 29lines1, labs1 = ax_a.get_legend_handles_labels() 30lines2, labs2 = ax_a2.get_legend_handles_labels() 31ax_a.legend(lines1 + lines2, labs1 + labs2, loc="upper center", frameon=False) 32 33# 第2部分:原始数据双Y轴面积图 34ax_b = axes[1] 35ax_b2 = ax_b.twinx() 36ax_b.fill_between(time_step, pressure, color="#b90b5f", alpha=0.3) 37ax_b2.fill_between(time_step, wind_speed, color="#06a7a7", alpha=0.3) 38ax_b.set_ylabel("Pressure (hPa)", color="#b90b5f") 39ax_b2.set_ylabel("Wind Speed (km/h)", color="#06a7a7") 40ax_b.set_title("Raw Data - Dual Area") 41ax_b.tick_params(axis="y", labelcolor="#b90b5f") 42ax_b2.tick_params(axis="y", labelcolor="#06a7a7") 43ax_b.set_xlim(0, 24) 44 45# 第3部分:压力渐变填充 + 注释 46ax_c = axes[2] 47# 构造多边形顶点 48verts = [] 49for i in range(len(time_step)-1): 50 verts.append([ 51 (time_step[i], 980), 52 (time_step[i], pressure[i]), 53 (time_step[i+1], pressure[i+1]), 54 (time_step[i+1], 980) 55 ]) 56poly = PolyCollection(verts, array=pressure[:-1], cmap="viridis", edgecolors="none") 57ax_c.add_collection(poly) 58ax_c.autoscale_view() 59ax_c.set_title("Pressure Gradient Fill") 60ax_c.set_xlabel("Time (hours)") 61ax_c.set_ylabel("Pressure (hPa)") 62# 标注最高点 63imax = np.argmax(pressure) 64ax_c.annotate("Peak", xy=(time_step[imax], pressure[imax]), 65 xytext=(time_step[imax]+2, pressure[imax]-10), 66 arrowprops=dict(arrowstyle="->", color="red")) 67 68for ax in axes: 69 ax.grid(True, linestyle="--", alpha=0.5) 70 71plt.show()