Python利用单行热力图绘制好看的风向风速

Python利用单行热力图绘制好看的风向风速

  • 导入所需支持库
  • 先画单行热力图表示风速
    • 设置画布
    • 设置风速数据
    • 设置色板
    • 利用seaborn绘制热力图
  • 画风向箭头
    • 换箭头函数
    • 导入风向数据
    • 导入计算坐标
    • 移动坐标轴
  • 完整代码

导入所需支持库

import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.colors as mcolors
import numpy as np

先画单行热力图表示风速

f, ax = plt.subplots(figsize=(3, 3))
plt.rcParams['font.sans-serif'] = ['SimHei']#解决中文乱码
uniform_data = []
wind_speed =  [2,4,4,3,4,2,1,1,1,2,1,2,1,2,1,1,1,1,0,0,0,1,0,1]
uniform_data.append(wind_speed)
colors = ['lightskyblue','darkturquoise','lime','greenyellow','orangered','red']
clrmap = mcolors.LinearSegmentedColormap.from_list("mycmap",colors)
x_time = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23']
sns.heatmap(uniform_data,square=True,annot=True, fmt="d",linewidths=.5,cmap=clrmap,yticklabels=['风速'],xticklabels=x_time,cbar=False,vmin=0,vmax=8,ax = ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=0)
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)

Python利用单行热力图绘制好看的风向风速_第1张图片

设置画布

f, ax = plt.subplots(figsize=(3, 3))
plt.rcParams['font.sans-serif'] = ['SimHei']#解决中文乱码

设置风速数据

uniform_data = []
wind_speed =  [2,4,4,3,4,2,1,1,1,2,1,2,1,2,1,1,1,1,0,0,0,1,0,1]
uniform_data.append(wind_speed)

这一步时风速列表变成一列数据,用于后续绘制单行热力图使用

设置色板

colors = ['lightskyblue','darkturquoise','lime','greenyellow','orangered','red']
clrmap = mcolors.LinearSegmentedColormap.from_list("mycmap",colors)

这里作者用的是自定义的色板,也可以不做这一步,使用matplotlib自带色板

利用seaborn绘制热力图

x_time = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23']
sns.heatmap(uniform_data,square=True,annot=True, fmt="d",linewidths=.5,cmap=clrmap,yticklabels=['风速'],xticklabels=x_time,cbar=False,vmin=0,vmax=8,ax = ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=0)
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)

sns.heatmap()函数中各参数含义可以自行去理解,这里作者就不赘述了,其中uniform_data是数据,yticklabels是纵坐标标签,vmin,vmax是数据最大最小值,配合色板显示颜色用。

画风向箭头

换箭头函数

def drawArrow(A, B ,ax_1):
    ax = ax_1.twinx()
    if A[0] ==B[0] and A[1] ==B[1]:
        ax.plot(A[0],A[1],'ko')
    else:
        ax.annotate("", xy=(B[0], B[1]), xytext=(A[0], A[1]),arrowprops=dict(arrowstyle="->"))
    ax.spines['left'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.set_xlim(0,24)
    ax.set_ylim(0,5)
    ax.get_yaxis().set_visible(False)
    ax.set_aspect('equal') #x轴y轴等比例
    plt.tight_layout()

上述是画箭头函数,读者可不必细究,后面作者会封装好给大家使用,其实原理就是在热力图的上面利用 ax.annotate()画箭头A, B分别为起始和终点坐标。

导入风向数据

wind_direction  =  [340,110,90,110,180,130,350,30,230,260,240,240,230,210,200,250,250,230,'c','c','c',100,'c',250]

导入计算坐标

for i in range(24):
    if wind_direction[i] != 'c':
        a = np.array([0.5+0.5*np.sin(wind_direction[i]/ 180 * np.pi)+i,3.5+0.5*np.cos(wind_direction[i]/ 180 * np.pi)])
        b = np.array([0.5-0.5*np.sin(wind_direction[i]/ 180 * np.pi)+i,3.5-0.5*np.cos(wind_direction[i]/ 180 * np.pi)])
        drawArrow(a,b,ax)
    else:
        a = np.array([0.5+i,3.5])
        drawArrow(a,a,ax)

这里作者画的是24小时整点风向风速,所以循环中为24,大家可以根据需要修改,'C’代表静风
Python利用单行热力图绘制好看的风向风速_第2张图片

移动坐标轴

ax.spines['bottom'].set_position(('data',1))

可以发现,画完风向以后时间轴被移动到下方,通过上述代码移动回热力图下
Python利用单行热力图绘制好看的风向风速_第3张图片

完整代码

import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.colors as mcolors
import numpy as np

def drawArrow(A, B ,ax_1):#画箭头
    ax = ax_1.twinx()
    if A[0] ==B[0] and A[1] ==B[1]:#静风画点
        ax.plot(A[0],A[1],'ko')
    else:
        ax.annotate("", xy=(B[0], B[1]), xytext=(A[0], A[1]),arrowprops=dict(arrowstyle="->"))
    ax.spines['left'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.set_xlim(0,24)
    ax.set_ylim(0,5)
    ax.get_yaxis().set_visible(False)
    ax.set_aspect('equal') #x轴y轴等比例
    plt.tight_layout()


def drow_wind_heatmap(wd,ws,xticklabels):
    f, ax = plt.subplots(figsize=(12, 12))
    plt.rcParams['font.sans-serif'] = ['SimHei']#解决中文乱码
    uniform_data = []
    uniform_data.append(ws)
    colors = ['lightskyblue','darkturquoise','lime','greenyellow','orangered','red']
    clrmap = mcolors.LinearSegmentedColormap.from_list("mycmap",colors)#自定义色标
    sns.heatmap(uniform_data,square=True,annot=True, fmt="d",linewidths=.5,cmap=clrmap,yticklabels=['风速'],xticklabels=xticklabels,cbar=False,vmin=0,vmax=8,ax = ax)
    ax.set_xticklabels(ax.get_xticklabels(), rotation=0)#坐标轴标签旋转
    ax.set_yticklabels(ax.get_yticklabels(), rotation=0)#坐标轴标签旋转
    ax.spines['bottom'].set_position(('data',1))#移动x轴


    for i in range(24):#画24个箭头
        if wd[i] != 'c':
            a = np.array([0.5+0.5*np.sin(wd[i]/ 180 * np.pi)+i,3.5+0.5*np.cos(wd[i]/ 180 * np.pi)])
            b = np.array([0.5-0.5*np.sin(wd[i]/ 180 * np.pi)+i,3.5-0.5*np.cos(wd[i]/ 180 * np.pi)])
            drawArrow(a,b,ax)
        else:#静风
            a = np.array([0.5+i,3.5])
            drawArrow(a,a,ax)

    plt.show()



if __name__ == "__main__":
    x_time = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23']
    wind_speed =  [2,4,4,3,4,2,1,1,1,2,1,2,1,2,1,1,1,1,0,0,0,1,0,1]
    wind_direction  =  [340,110,90,110,180,130,350,30,230,260,240,240,230,210,200,250,250,230,'c','c','c',100,'c',250]
    drow_wind_heatmap(wind_direction,wind_speed,x_time)


你可能感兴趣的:(python,matplotlib,数据分析)