小言_互联网的博客

python 可视化plotly 等高线热力图

288人阅读  评论(0)

python 可视化plotly 等高线热力图

CSV文件数据如下,要求将第1列转速设置为x轴,第2列扭矩设置为y轴,第3列效率为等高线。

思路分析:
1)在控制端输入文件路径,读取csv文件,该代码只对三列数据进行处理,多于或少于三列都会报错退出,且数据行只有第一行,且其余是数据行。对数据进行空数据行删除处理。
2)数据的预处理,x是第1列数据,y是第2列数据,画等高线Z则是一个数组,其数据格式应该如下,即相同扭矩下不同转速的效率组成的数组。也就是CSV文件格式要转化为以下格式。首先要把所有转速和扭矩下的效率全部显示出来。需要用到笛卡尔积, 即x(1000-16000一个16个值) 与y(20-300 15个值)生成一个只含有X和Y两列的数据集,再与原数据合并生成新的数据集,没有效率值则自动生成NAN值。这时再对NAN值进行赋予0值。再遍历y从20-300,获取每个y下面不同的效率值是一个list,同时又是列表index_list1的值。
3)将2中获取的x,y, index_list1传入画图的函数中,进行plotly作图。

# -*- coding:utf8 -*-
import numpy as np
import pandas as pd
import plotly.graph_objs as go
import plotly.offline as py  #设置离线画图


""" 打开原始CSV文件数据,并且检查输入查询的列名是否存在于文件中,
    若存在,则提取这些列的数据,返回新的dataframe,
    若不存在,则报错不执行程序
    返回值: new_Df
"""
def check_file_column():
    input_file = input('请输入csv文件路径:')
    filename = input_file.strip()
    with open(filename, 'rb') as f:
        csv_data = pd.read_csv(f, encoding='gb2312')
    if len(csv_data.columns) != 3:
        print('文件列名不等于3列,请修改文件!')
        exit()
    correct_list = list(csv_data.columns.values)
    # 删除空的数据行
    new_Df = csv_data.dropna()
    # 将导入的各个类型变成正确的类型
    new_Df[new_Df.columns.values[0]] = new_Df[new_Df.columns.values[0]].apply(int)
    new_Df[new_Df.columns.values[2]] = new_Df[new_Df.columns.values[2]].apply(float)
    new_Df[new_Df.columns.values[1]] = new_Df[new_Df.columns.values[1]].apply(float)
    # 将new_Df进行排序
    new_Df.sort_values(new_Df.columns.values[0], inplace=True)
    return new_Df, correct_list


""" 数据的处理:
    传入参数x 是第一列去重列表,参数y是第二列去重列表,csv_data是提取相应列名的数据集
    将x,y调用函数笛卡尔积生成新的dataframe,并且与csv_data合并,给空值赋0
    将所有转矩的效率提取到一个二维数组index_list1
    返回: index_list1 
"""
def handle_data(x,y,csv_data):
    new_pd = itertool_func(x, y,csv_data)
    new_pd[csv_data.columns.values[0]] = new_pd[csv_data.columns.values[0]].apply(int)
    new_pd[csv_data.columns.values[1]] = new_pd[csv_data.columns.values[1]].apply(int)
    # 合并两个dataframe,与原来的数据集为基础
    df3 = pd.merge(csv_data, new_pd, how='right', on=list(new_pd.columns.values))
    # 给空值赋予0
    df4 = df3.fillna(value=0)
    index_list1 = []
    for y1 in y:
        index_list1.append(df4.loc[df4[csv_data.columns.values[1]] == y1][csv_data.columns.values[2]].values)
    return index_list1


""" 传入参数A是x数组, 参数B是y数组
将两个数组进行笛卡尔积操作生成新的数据集"""
def itertool_func(A,B,csv_data):
    lenB = len(B)
#     print(lenB)
    new_pd = pd.DataFrame(columns=csv_data.columns.values[:2])
    for a in A:
        curA = np.array([a]*lenB)
        curA.shape = (lenB,1)
        curB = np.array(B)
        curB.shape = (lenB,1)
        join_h = np.hstack((curA, curB))
        new_pd = new_pd.append(pd.DataFrame(join_h, columns=csv_data.columns.values[:2]), ignore_index=True)
    return new_pd


"""传入参数x,参数y,参数z是二维数组,反映效率
画等高线图
"""
def plot_color(x, y, z):
    fig = go.Figure(
        data=go.Contour(
            z=z,
            x=x,  # horizontal axis
            y=y,  # vertical axis
            # colorscale=[[0, 'white'], [0.5, 'red'], [1.0, 'rgb(0, 0, 255)']],
            colorscale=[[0, 'white'], [0.5, 'red'], [1.0, 'darkred']],
            contours=dict(
                start=60,    # colorbar的最小刻度值
                end=100,   #colorbar的最大刻度值
                size=4,      #即每个4画一个等高线
                showlabels=True,  # show labels on contours
                labelfont=dict(  # label font properties
                    size=12,
                    color='white',
                ),
            ),

        ))
    fig.update_layout(  # all "layout" attributes: /python/reference/#layout
        title=dict(text="Motor Efficiency Presented by matplotlib", font=dict(family='Arial', size=24, color='black')),
        xaxis=dict(  # all "layout's" "xaxis" attributes: /python/reference/#layout-xaxis
            title="Speed",  # more about "layout's" "xaxis's" "title": /python/reference/#layout-xaxis-title
            titlefont=dict(color='black', size=24)  # 设置坐标轴标签的字体及颜色
        ),
        yaxis=dict(
            title='Torque',
            titlefont=dict(color='black', size=24)  # 设置坐标轴标签的字体及颜色

        ),
    )
    fig.show()
    py.plot(fig, filename='pictures/contour.html',  # 会生成一个网页文件
            image='png', )  # 设置保存的文件类型,不会在本地有个png的文件,需要在生成的网页打开另存为png的文件


def main():
    csv_data, correct_list = check_file_column()
    # 选取第一列的所有值并去重并排序,设置为X坐标,
    col_1 = csv_data.iloc[:,0]
    x = sorted(list(set(col_1.values)))
    # 选取第2列所有值并去重并排序,设置为Y坐标
    col_2 = csv_data.iloc[:,1]
    y = sorted(list(set(col_2.values)))
    # 处理数据
    index_list1 = handle_data(x,y,csv_data)
    # 画图
    plot_color(x, y, index_list1)


if __name__ == '__main__':
    main()

最后生成一个网页,鼠标放在图上会显示x,y,z的相应值,而且网页右上方有照相功能,点击之后浏览器能够自动下载png图片。上面的代码 py.plot有本地离线下载网页的功能。


转载:https://blog.csdn.net/weixin_38040408/article/details/101213189
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场