python可視化動態圖表: 關於pyecharts的sankey桑基圖繪製

最近因工做緣由,須要處理一些數據,順便學習一下動態圖表的繪製。本質是使具備源頭的流動信息可以準確找到其上下級關係和流向。html

數據來源是csv文件 導入成爲dataframe以後,列爲其車輛的各部件供應商公司名稱或其自身的屬性。node

導入後通過處理指望是看到整個工業的供應鏈和市場份額.python

 

結果的部分截圖: 架構

數據來源:app

核心是將以上數據處理成接口須要的兩個數據,一個是全部節點的名稱。另外一個是節點之間互相連接的值,見下圖echarts

NODE: 全部桑基圖的節點集合ide

 

 link: 每個數據流的起始,結束,與值。學習

核心統計原理是:spa

先肯定從左到右的統計大綱:在本次案例中爲:excel

接下來就是找大綱序列中當前大類中對應下一級的小類的數目,例: 案例第一步即找最高車速段中 最高車速能力在<180km/h的篩選出來,同時找出低速度段且續駛里程>80km的數量.

統計代碼:

# link 數據架構
link=[]
for i in range(len(title)):
    temp0=list(class_item)
    for j in list(class_item[temp0[i]]):
        try:
            for k in list(class_item[temp0[i+1]]):
                df1=df[df[temp0[i]]==j]
                df2=df1[df1[temp0[i+1]]==k]
                temp_value=len(df2)
                if temp_value!=0:
                    link.append({'source':j,
                                 'target':k,
                                 'value':temp_value})
                    del df1
                    del df2
        except:
            continue

 

總代碼:

# 數據架構 總領數據架構-品牌-車輛用途-
import matplotlib.pyplot as plt
from pyecharts import Pie,Bar,Page,Bar3D,Overlap,Line,Boxplot,Surface3D,Sankey,EffectScatter
import pandas as pd
import numpy as np
df=pd.read_excel(r'C:\Users\wenzhe.tian\Desktop\數據分析\北理新能源數據v2\02_20190301\2EV_v2.xlsx','Sheet1')
df_ori=df.copy()
#數據處理部分 添加項目,替換重複 格式統一 去掉空格 等
df=df[df.技術類型.str.contains('EV',regex=False)]
df=df.reset_index()
df=df.drop('index',axis=1)

#數據格式處理
df['車型分類']=df['車型分類'].fillna('nan')
df=df[~df['車型分類'].isin(['nan'])] # 江淮ES8供應商數據大量缺失,故排除 也可drop
df['電動汽車續駛里程(工況法,km)']=df['電動汽車續駛里程(工況法,km)'].fillna(0)
df['車輛品牌']=df['車輛品牌'].map(str).replace('傳祺(Trumpchi)牌','傳祺(Trumpchi)牌')
df['通用名稱'][df['電動汽車續駛里程(工況法,km)']==0]='ES8'
df['電動汽車續駛里程(工況法,km)'][df['電動汽車續駛里程(工況法,km)']==0]=355
df['電動汽車續駛里程(工況法,km)'][df['電動汽車續駛里程(工況法,km)']=='155(對應整備質量750kg),165(對應整備質量700kg)']=165
df['電動汽車續駛里程(工況法,km)'][df['電動汽車續駛里程(工況法,km)']==170203203]=255
df['電動汽車續駛里程(工況法,km)']=df['電動汽車續駛里程(工況法,km)'].fillna(0)
df['最高車速']=df['最高車速'].astype(int)
df['電動汽車續駛里程(工況法,km)']=df['電動汽車續駛里程(工況法,km)'].astype(int)
df['最高車速段']=df['最高車速'].astype(str)
df['續駛里程段']=df['電動汽車續駛里程(工況法,km)'].astype(str)

#df['電池能量密度']=df['電池容量']*df['儲能裝置總成標稱電壓(V)']/df['儲能裝置總成質量(kg)']


df['整備質量(kg)'][(df['整備質量(kg)'].isnull()) | (df["整備質量(kg)"].apply(lambda x: str(x).isspace()))]=2390
# 去掉先後空格
title=list(df)
df['儲能裝置單體質量(kg)']=df['儲能裝置單體質量(kg)'].astype(str)
for i in title:
    try:
        df[i]=df[i].map(str.strip)
    except:
        continue

#重複值處理        
df=df.replace('比亞迪汽車工業有限公司,比亞迪汽車工業有限公司', '比亞迪汽車工業有限公司')
df=df.replace('比亞迪汽車工業有限公司/比亞迪汽車工業有限公司', '比亞迪汽車工業有限公司')
df=df.replace('山東德洋電子科技有限公司,山東德洋電子科技有限公司', '山東德洋電子科技有限公司')
df=df.replace('深圳市大地和電氣股份有限公司(軟件)/深圳市大地和電氣股份有限公司(硬件)', '大地和電氣')
df['最高車速段'][(df['最高車速']<=180)]='<180km/h'
df['最高車速段'][((df['最高車速']<=200)& (df['最高車速']>180))]='180-200km/h'
df['最高車速段'][(df['最高車速']>200)]='>200km/h'

df['續駛里程段'][(df['電動汽車續駛里程(工況法,km)']<=60)]='<60km'
df['續駛里程段'][((df['電動汽車續駛里程(工況法,km)']<=80)& (df['電動汽車續駛里程(工況法,km)']>60))]='60-80km'
df['續駛里程段'][(df['電動汽車續駛里程(工況法,km)']>80)]='>80km'
title=['最高車速段','續駛里程段','車輛用途','企業名稱','車型分類','車輛品牌',
       '電機生產商','電動汽車整車控制器生產企業','電動汽車車載充電機生產企業','儲能裝置總成生產企業','車載能源管理系統生產企業']

#無效值處理  
for i in title:
    df[i]=df[i].astype(str)
    df[i]=df[i].map(lambda x: x.replace('有限公司','').replace('股份','').replace('公司','').replace('','').replace(' Company','').replace(' company','').replace('','品牌').replace('北京新能源汽車','北汽新能源'))
    df[i]=df[i].map(lambda x: x.replace('浙江','').replace('山東','').replace('廣州汽車集團乘用車','廣汽').replace('杭州','').replace('江西','').replace('合肥',''))
    df[i]=df[i].map(lambda x: x.replace('深圳市','').replace('永康市','').replace('珠海','').replace('鄭州','').replace('軟件:','').replace('硬件:','').replace('北京:','').replace('長沙市','').replace('金華市',''))
    df[i]=df[i].map(lambda x: x.replace('nan','北汽新能源').replace('','(').replace('',')').replace('()','').replace('/深圳市大地和電氣','').replace('開發企業','').replace('生產企業','').replace('福建省汽車工業集團雲度新能源汽車','雲度新能源'))
    df[i]=df[i].map(lambda x: x.replace('電機1:華域汽車電動系統/電機2:華域汽車電動系統','華域汽車電動系統').replace('前:蔚然(南京)動力科技/後:蔚然(南京)動力科技','蔚然(南京)動力科技'))
    if i =='最高車速段':
        str_item='最高車速'
    elif i =='續駛里程段':
        str_item='續航里程'
    elif i =='電機生產商':
        str_item='MOT'        
    elif i =='電動汽車整車控制器生產企業':
        str_item='MC'
    elif i =='電動汽車車載充電機生產企業':
        str_item='OBC'
    elif i =='儲能裝置總成生產企業':
        str_item='BAT'
    elif i =='車載能源管理系統生產企業':
        str_item='BMS'
    else:
        str_item=''
        
    df[i]=df[i].map(lambda x: str_item+x)  
    

class_item={}
for i in title:
    class_item[i]=df[i].drop_duplicates()

    
node=[]
for i in title:    
    for j in list(class_item[i]):
        node.append({'name':j})
# link 數據架構
link=[]
for i in range(len(title)):
    temp0=list(class_item)
    for j in list(class_item[temp0[i]]):
        try:
            for k in list(class_item[temp0[i+1]]):
                df1=df[df[temp0[i]]==j]
                df2=df1[df1[temp0[i+1]]==k]
                temp_value=len(df2)
                if temp_value!=0:
                    link.append({'source':j,
                                 'target':k,
                                 'value':temp_value})
                    del df1
                    del df2
        except:
            continue
                    

sankey = Sankey("EV供應商鏈統計",width=6000, height=700)
sankey.use_theme('roma') #roma wonderland
sankey.add(
    "EV供應商統計",
    node,
    link,
    line_opacity=0.2,
    line_curve=0.3,
    line_color='source',
    sankey_node_gap=13,
    is_label_show=True,
    label_pos="right",
    is_legend_show =False,
    label_text_size=11
)
sankey.render('EV供應商統計_All.html')
del sankey

sankey = Sankey("EV供應商鏈統計",width=6000, height=1500)
sankey.use_theme('roma') #roma wonderland
sankey.add(
    "EV供應商統計",
    node,
    link,
    line_opacity=0.2,
    line_curve=0.3,
#    line_color='source',
    sankey_node_gap=13,
    is_label_show=True,
    label_pos="right",
    is_legend_show =False,
    label_text_size=12
)
sankey.render('EV供應商統計_All_v2.html')
View Code

 

(以前是用plotly,後來發現pyecharts接口稍微簡單些,其實都差很少,但plotyly能夠一些特殊地圖繪製比pyecharts來的精細,因此看繪圖需求吧)

附上連接:https://plot.ly/python/   https://pyecharts.org/#/zh-cn/intro  用於查閱須要繪製的圖的種類

相關文章
相關標籤/搜索