You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.0 KiB

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()