python详解绘制风玫瑰图

绘制风玫瑰图

# 导入包
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段,每列数据表示各方向风速的频数统计值
N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW
0~0.2 192 67 137 212 271 215 29 231 297 262 107 90 108 213 59 107
0.3~1.5 194 108 185 45 92 285 135 263 217 119 197 263 167 167 285 205
1.6~3.3 147 52 51 222 264 171 183 203 48 148 148 73 58 264 293 125
3.4~5.4 62 51 277 77 139 287 102 111 119 73 141 104 223 282 67 147

绘制频数风速玫瑰图:

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

python详解绘制风玫瑰图_第1张图片
已经可以初步满足需求了,不过我们发现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()

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

数据转化为百分比

_sum = data.apply(np.sum)
data = data / _sum
data
N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW
0~0.2 0.322689 0.241007 0.210769 0.381295 0.353786 0.224426 0.064588 0.285891 0.436123 0.435216 0.180438 0.169811 0.194245 0.230022 0.083807 0.183219
0.3~1.5 0.326050 0.388489 0.284615 0.080935 0.120104 0.297495 0.300668 0.325495 0.318649 0.197674 0.332209 0.496226 0.300360 0.180346 0.404830 0.351027
1.6~3.3 0.247059 0.187050 0.078462 0.399281 0.344648 0.178497 0.407572 0.251238 0.070485 0.245847 0.249578 0.137736 0.104317 0.285097 0.416193 0.214041
3.4~5.4 0.104202 0.183453 0.426154 0.138489 0.181462 0.299582 0.227171 0.137376 0.174743 0.121262 0.237774 0.196226 0.401079 0.304536 0.095170 0.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()

python详解绘制风玫瑰图_第3张图片

你可能感兴趣的:(数据可视化)