import numpy as np import matplotlib.pyplot as plt import pandas as pd from matplotlib.projections.polar import PolarAxes from matplotlib.transforms import Affine2D, IdentityTransform # 假设你的风向数据如下 wind_data = [(0, 10), (45, 15), (90, 20), (135, 25), (180, 30), (225, 25), (270, 20), (315, 15)] # 创建DataFrame并计算总频率 df = pd.DataFrame(wind_data, columns=['direction', 'frequency']) total_frequency = df['frequency'].sum() # 转换角度为弧度 directions_rad = df['direction'].values * np.pi / 180 # 计算每个扇区的弧度长度 sector_angles = df['frequency'] / total_frequency * 2 * np.pi # 定义自定义变换,用于添加网格线 def wind_direction_transform(ax): theta = np.deg2rad(np.arange(0, 360, 45)) r = np.ones_like(theta) xx, yy = np.meshgrid(theta, r) return Affine2D().rotate_deg(90).translate(-xx.ravel(), yy.ravel()) # 绘制玫瑰图 fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(8, 8)) # 自定义颜色 colors = ['skyblue', 'deepskyblue', 'dodgerblue', 'blue', 'mediumblue', 'darkblue', 'midnightblue', 'slateblue'] # 绘制每个风向区段 for i, ((direction, freq), color) in enumerate(zip(wind_data, colors)): angle = direction * np.pi / 180 ax.bar([angle], [freq], width=2 * np.pi / 360, bottom=0, color=color, edgecolor='white', alpha=0.8) # 手动绘制网格线 theta_ticks = np.deg2rad(np.arange(0, 360, 45)) # 45度间隔的网格线 for angle in theta_ticks: ax.plot([angle, angle], [0, 1], transform=ax.get_yaxis_transform(), color='gray', ls='--', lw=0.5, zorder=1) # 添加指南针标签 labels = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'] angles = np.arange(0, 2*np.pi, 2*np.pi/8) ax.set_thetagrids(angles * 180/np.pi, labels, fontproperties={'weight': 'bold'}) # 隐藏中心轴 ax.axis('off') # 替换掉原来的ax.set_raxis_visible(False) # 自定义中心点 ax.set_theta_zero_location('N') ax.set_theta_direction(-1) # 添加标题 ax.set_title('Wind Rose Diagram', fontweight='bold') plt.show()