python详解绘制风玫瑰图

it2022-05-05  141

绘制风玫瑰图

# 导入包 import numpy as np import pandas as pd import matplotlib.pyplot as plt #-------设置支持中文----------------------# import matplotlib as mpl mpl.rcParams['font.sans-serif'] = ['SimHei'] #设置简黑字体 mpl.rcParams['axes.unicode_minus'] = False #-------自定义坐标轴刻度格式----------------# from matplotlib.ticker import FuncFormatter

创建数据集:

np.random.seed(0) data = pd.DataFrame(np.random.randint(20, 300, (4, 16)), index=['0~0.2', '0.3~1.5', '1.6~3.3', '3.4~5.4'], columns='N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW'.split()) data #风速选择了4段,每列数据表示各方向风速的频数统计值 NNNENEENEEESESESSESSSWSWWSWWWNWNWNNW0~0.2192671372122712152923129726210790108213591070.3~1.519410818545922851352632171191972631671672852051.6~3.314752512222641711832034814814873582642931253.4~5.46251277771392871021111197314110422328267147

绘制频数风速玫瑰图:

N = 16 # 风速分布为16个方向 theta = np.linspace(0, 2*np.pi, N, endpoint=False) # 获取16个方向的角度值 width = np.pi / N # 绘制扇型的宽度,可以自行调整 labels = list(data.columns) # 自定义坐标标签为 N , NSN, …… # 开始绘图 plt.figure(figsize=(8,8)) ax = plt.subplot(111, projection='polar') for idx in data.index: # 每一行绘制一个扇形 radii = data.loc[idx] # 每一行数据 ax.bar(theta, radii, width=width, bottom=0.0, label=idx, tick_label=labels) plt.title('风玫瑰图示意图') plt.legend(loc=4, bbox_to_anchor=(1.15, -0.07)) # 将label显示出来, 并调整位置 plt.show()

已经可以初步满足需求了,不过我们发现N位置差了90°,而且为了满足‘上北下南左西右东’的习惯,需要逆时针方向绘制。所以做两个修改:

N = 16 # 风速分布为16个方向 theta = np.linspace(0, 2*np.pi, N, endpoint=False) # 获取16个方向的角度值 width = np.pi / N # 绘制扇型的宽度,可以自行调整 labels = list(data.columns) # 自定义坐标标签为 N , NSN, …… # 开始绘图 plt.figure(figsize=(8,8)) ax = plt.subplot(111, projection='polar') for idx in data.index: # 每一行绘制一个扇形 radii = data.loc[idx] # 每一行数据 ax.bar(theta, radii, width=width, bottom=0.0, label=idx, tick_label=labels) #------------------------------------# ax.set_theta_zero_location('N') #设置零度方向北 ax.set_theta_direction(-1) # 逆时针方向绘图 plt.title('风玫瑰图示意图') plt.legend(loc=4, bbox_to_anchor=(1.15, -0.07)) # 将label显示出来, 并调整位置 plt.show()

这样基本满足我们的需求了,但是有的时候我们需要绘制百分比玫瑰图,下面我们讨论如何制作百分比风玫瑰图:

数据转化为百分比

_sum = data.apply(np.sum) data = data / _sum data NNNENEENEEESESESSESSSWSWWSWWWNWNWNNW0~0.20.3226890.2410070.2107690.3812950.3537860.2244260.0645880.2858910.4361230.4352160.1804380.1698110.1942450.2300220.0838070.1832190.3~1.50.3260500.3884890.2846150.0809350.1201040.2974950.3006680.3254950.3186490.1976740.3322090.4962260.3003600.1803460.4048300.3510271.6~3.30.2470590.1870500.0784620.3992810.3446480.1784970.4075720.2512380.0704850.2458470.2495780.1377360.1043170.2850970.4161930.2140413.4~5.40.1042020.1834530.4261540.1384890.1814620.2995820.2271710.1373760.1747430.1212620.2377740.1962260.4010790.3045360.0951700.251712

数据转化成功,我们绘制图片唯一要修改的就是yaxis(本质是bar图,我们仔细观察上面的图不难发现原因)刻度的表达,将其转化为百分比:

N = 16 # 风速分布为16个方向 theta = np.linspace(0, 2*np.pi, N, endpoint=False) # 获取16个方向的角度值 width = np.pi / N # 绘制扇型的宽度,可以自行调整 labels = list(data.columns) # 自定义坐标标签为 N , NSN, …… # 开始绘图 plt.figure(figsize=(8,8)) ax = plt.subplot(111, projection='polar') for idx in data.index: # 每一行绘制一个扇形 radii = data.loc[idx] # 每一行数据 ax.bar(theta, radii, width=width, bottom=0.0, label=idx, tick_label=labels) #------------------------------------# ax.set_theta_zero_location('N') #设置零度方向北 ax.set_theta_direction(-1) # 逆时针方向绘图 #--------自定义yaxis的刻度格式-----------# plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda s, position: '{:.0f}%'.format(100*s))) plt.title('风玫瑰图示意图') plt.legend(loc=4, bbox_to_anchor=(1.15, -0.07)) # 将label显示出来, 并调整位置 plt.show()


最新回复(0)