1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Python 繪制驚艷的?;鶊D

        共 9676字,需瀏覽 20分鐘

         ·

        2022-02-21 18:59

        導讀:本文中,我們使用 Python 的 plotly 繪制?;鶊D。


        作者:云朵君
        來源:數(shù)據(jù)STUDIO(ID:jim_learning)


        01 ?;鶊D簡介

        很多時候,我們需要一種必須可視化數(shù)據(jù)如何在實體之間流動的情況。例如,以居民如何從一個國家遷移到另一個國家為例。這里演示了有多少居民從英格蘭遷移到北愛爾蘭、蘇格蘭和威爾士。


        從這個?;鶊D (Sankey)可視化中可以明顯看出,從England遷移到Wales的居民多于從Scotland或Northern Ireland遷移的居民。

        什么是?;鶊D?

        ?;鶊D通常描繪從一個實體(或節(jié)點)到另一個實體(或節(jié)點)的數(shù)據(jù)流。

        數(shù)據(jù)流向的實體被稱為節(jié)點,數(shù)據(jù)流起源的節(jié)點是源節(jié)點(例如左側(cè)的England),流結(jié)束的節(jié)點是目標節(jié)點(例如右側(cè)的Wales)。源節(jié)點和目標節(jié)點通常表示為帶有標簽的矩形。

        流動本身由直線或曲線路徑表示,稱為鏈接流/鏈接的寬度與流的量/數(shù)量成正比。在上面的例子中,從英格蘭到威爾士的流動(即居民遷移)比從英格蘭到蘇格蘭或北愛爾蘭的流動(即居民遷移)更廣泛(更多),表明遷移到威爾士的居民數(shù)量多于其他國家。

        ?;鶊D可用于表示能量、金錢、成本的流動,以及任何具有流動概念的事物。

        米納爾關(guān)于拿破侖入侵俄羅斯的經(jīng)典圖表可能是?;鶊D表最著名的例子。這種使用?;鶊D的可視化非常有效地顯示了法國軍隊在前往俄羅斯和返回的途中是如何進步(或減少?)的。


        本文中,我們使用 Python 的 plotly 繪制桑基圖。


        02 如何繪制?;鶊D?

        本文使用 2021 年奧運會數(shù)據(jù)集繪制?;鶊D。該數(shù)據(jù)集包含有關(guān)獎牌總數(shù)的詳細信息——國家、獎牌總數(shù)以及金牌、銀牌和銅牌的單項總數(shù)。我們通過繪制一個?;鶊D來了解一個國家贏得的金牌、銀牌和銅牌數(shù)。

        df_medals?=?pd.read_excel("data/Medals.xlsx")
        print(df_medals.info())
        df_medals.rename(columns={'Team/NOC':'Country',?'Total':?'Total?Medals',?'Gold':'Gold?Medals',?'Silver':?'Silver?Medals',?'Bronze':?'Bronze?Medals'},?inplace=True)
        df_medals.drop(columns=['Unnamed:?7','Unnamed:?8','Rank?by?Total'],?inplace=True)

        df_medals

        <class?'pandas.core.frame.DataFrame'>
        RangeIndex:?93?entries,?0?to?92
        Data?columns?(total?9?columns):
        #???Column?????????Non-Null?Count??Dtype??
        ---??------?????????--------------??-----??
        0???Rank???????????93?non-null?????int64??
        1???Team/NOC???????93?non-null?????object
        2???Gold???????????93?non-null?????int64??
        3???Silver?????????93?non-null?????int64??
        4???Bronze?????????93?non-null?????int64??
        5???Total??????????93?non-null?????int64??
        6???Rank?by?Total??93?non-null?????int64??
        7???Unnamed:?7?????0?non-null??????float64
        8???Unnamed:?8?????1?non-null??????float64
        dtypes:?float64(2),?int64(6),?object(1)
        memory?usage:?6.7+?KB
        None


        1. ?;鶊D繪圖基礎(chǔ)

        使用?plotly?的?go.Sankey,該方法帶有2 個參數(shù) ——?nodes??和?links?(節(jié)點和鏈接)。

        注意:所有節(jié)點——源和目標都應該有唯一的標識符。

        在本文奧林匹克獎牌數(shù)據(jù)集情況中:

        Source是國家。將前 3 個國家(美國、中國和日本)視為源節(jié)點。用以下(唯一的)標識符、標簽和顏色來標記這些源節(jié)點:

        • 0:美國:綠色
        • 1:中國:藍色
        • 2:日本:橙色

        Target是金牌、銀牌或銅牌。用以下(唯一的)標識符、標簽和顏色來標記這些目標節(jié)點:

        • 3:金牌:金色
        • 4:銀牌:銀色
        • 5:銅牌:棕色

        Link(源節(jié)點和目標節(jié)點之間)是每種類型獎牌的數(shù)量。在每個源中有3個鏈接,每個鏈接都以目標結(jié)尾——金牌、銀牌和銅牌。所以總共有9個鏈接。每個環(huán)節(jié)的寬度應為金牌、銀牌和銅牌的數(shù)量。用以下源標記這些鏈接到目標、值和顏色:

        • 0 (美國) 至 3,4,5 : 39, 41, 33
        • 1 (中國) 至 3,4,5 : 38, 32, 18
        • 2 (日本) 至 3,4,5 : 27, 14, 17

        需要實例化 2 個?python dict?對象來表示

        • nodes?(源和目標):標簽和顏色作為單獨的列表和
        • links:源節(jié)點、目標節(jié)點、值(寬度)和鏈接的顏色作為單獨的列表

        并將其傳遞給plotly的?go.Sankey。

        列表的每個索引(標簽、源、目標、值和顏色)分別對應一個節(jié)點或鏈接。

        NODES?=?dict(?
        #?????????0???????????????????????????1?????????????????????????????2????????3???????4?????????5?????????????????????????
        label?=?["United?States?of?America",?"People's?Republic?of?China",?"Japan",?"Gold",?"Silver",?"Bronze"],
        color?=?["seagreen",?????????????????"dodgerblue",?????????????????"orange",?"gold",?"silver",?"brown"?],)
        LINKS?=?dict(???
        ??source?=?[??0,??0,??0,??1,??1,??1,??2,??2,??2],?#?鏈接的起點或源節(jié)點
        ??target?=?[??3,??4,??5,??3,??4,??5,??3,??4,??5],?#?鏈接的目的地或目標節(jié)點
        ??value?=??[?39,?41,?33,?38,?32,?18,?27,?14,?17],?#?鏈接的寬度(數(shù)量)
        #?鏈接的顏色
        #?目標節(jié)點:???????3-Gold??????????4-Silver????????5-Bronze
        ??color?=?[???
        ??"lightgreen",???"lightgreen",???"lightgreen",??????#?源節(jié)點:0?-?美國?States?of?America
        ??"lightskyblue",?"lightskyblue",?"lightskyblue",????#?源節(jié)點:1?-?中華人民共和國China
        ??"bisque",???????"bisque",???????"bisque"],)????????#?源節(jié)點:2?-?日本
        data?=?go.Sankey(node?=?NODES,?link?=?LINKS)
        fig?=?go.Figure(data)
        fig.show()


        這是一個非?;镜纳;鶊D。但是否注意到圖表太寬并且銀牌出現(xiàn)在金牌之前?

        接下來介紹如何調(diào)整節(jié)點的位置和寬度。

        2. 調(diào)整節(jié)點位置和圖表寬度

        為節(jié)點添加 x 和 y 位置以明確指定節(jié)點的位置。值應介于 0 和 1 之間。

        NODES?=?dict(?
        #?????????0???????????????????????????1?????????????????????????????2????????3???????4?????????5?????????????????????????
        label?=?["United?States?of?America",?"People's?Republic?of?China",?"Japan",?"Gold",?"Silver",?"Bronze"],
        color?=?["seagreen",?????????????????"dodgerblue",?????????????????"orange",?"gold",?"silver",?"brown"?],)
        x?=?[?????0,??????????????????????????0,????????????????????????????0,????????0.5,????0.5,??????0.5],
        y?=?[?????0,??????????????????????????0.5,??????????????????????????1,????????0.1,????0.5,????????1],)
        data?=?go.Sankey(node?=?NODES,?link?=?LINKS)
        fig?=?go.Figure(data)
        fig.update_layout(title="Olympics?-?2021:?Country?&??Medals",??font_size=16)
        fig.show()

        于是得到了一個緊湊的?;鶊D:


        下面看看代碼中傳遞的各種參數(shù)如何映射到圖中的節(jié)點和鏈接。

        ▲代碼如何映射到?;鶊D

        3. 添加有意義的懸停標簽

        我們都知道plotly繪圖是交互的,我們可以將鼠標懸停在節(jié)點和鏈接上以獲取更多信息。

        ▲帶有默認懸停標簽的?;鶊D

        當將鼠標懸停在圖上,將會顯示詳細信息。懸停標簽中顯示的信息是默認文本:節(jié)點、節(jié)點名稱、傳入流數(shù)、傳出流數(shù)和總值。

        例如:

        • 節(jié)點美國共獲得11枚獎牌(=39金+41銀+33銅)
        • 節(jié)點金牌共有104枚獎牌(=美國39枚,中國38枚,日本27枚)

        如果我們覺得這些標簽太冗長了,我們可以對此進程改進。使用hovertemplate參數(shù)改進懸停標簽的格式

        • 對于節(jié)點,由于hoverlabels 沒有提供新信息,通過傳遞一個空hovertemplate = ""來去掉hoverlabel
        • 對于鏈接,可以使標簽簡潔,格式為-
        • 對于節(jié)點和鏈接,讓我們使用后綴"Medals"顯示值。例如 113 枚獎牌而不是 113 枚。這可以通過使用具有適當valueformatvaluesuffixupdate_traces函數(shù)來實現(xiàn)。

        NODES?=?dict(?
        #?????????0???????????????????????????1???????????????????????????????2????????3???????4???????????5
        label?=?["United?States?of?America",?"People's?Republic?of?China",???"Japan",?"Gold",?"Silver",?"Bronze"],
        color?=?[????????????????"seagreen",?????????????????"dodgerblue",??"orange",?"gold",?"silver",?"brown"?],
        x?????=?[?????????????????????????0,????????????????????????????0,?????????0,????0.5,??????0.5,??????0.5],
        y?????=?[?????????????????????????0,??????????????????????????0.5,?????????1,????0.1,??????0.5,????????1],
        hovertemplate="?",)

        LINK_LABELS?=?[]
        for?country?in?["USA","China","Japan"]:
        ????for?medal?in?["Gold","Silver","Bronze"]:
        ????????LINK_LABELS.append(f"{country}-{medal}")
        LINKS?=?dict(source?=?[??0,??0,??0,??1,??1,??1,??2,??2,??2],?
        ???????#?鏈接的起點或源節(jié)點
        ???????target?=?[??3,??4,??5,??3,??4,??5,??3,??4,??5],?
        ???????#?鏈接的目的地或目標節(jié)點
        ???????value?=??[?39,?41,?33,?38,?32,?18,?27,?14,?17],?
        ???????#?鏈接的寬度(數(shù)量)?
        ?????????????#?鏈接的顏色
        ?????????????#?目標節(jié)點:3-Gold??????????4?-Silver????????5-Bronze
        ?????????????color?=?["lightgreen",???"lightgreen",???"lightgreen",???#?源節(jié)點:0?-?美國
        ??????????????????????"lightskyblue",?"lightskyblue",?"lightskyblue",?#?源節(jié)點:1?-?中國
        ??????????????????????"bisque",???????"bisque",???????"bisque"],??????#?源節(jié)點:2?-?日本
        ?????????????label?=?LINK_LABELS,?
        ?????????????hovertemplate="%{label}",)

        data?=?go.Sankey(node?=?NODES,?link?=?LINKS)
        fig?=?go.Figure(data)
        fig.update_layout(title="Olympics?-?2021:?Country?&??Medals",??
        ??????????????????font_size=16,?width=1200,?height=500,)
        fig.update_traces(valueformat='3d',?
        ??????????????????valuesuffix='Medals',?
        ??????????????????selector=dict(type='sankey'))
        fig.update_layout(hoverlabel=dict(bgcolor="lightgray",
        ??????????????????????????????????font_size=16,
        ??????????????????????????????????font_family="Rockwell"))
        fig.show("png")?#fig.show()

        ▲帶有改進的懸停標簽的?;鶊D

        4. 對多個節(jié)點和級別進行泛化

        相對于鏈接,節(jié)點被稱為源和目標。作為一個鏈接目標的節(jié)點可以是另一個鏈接的源。

        • 該代碼可以推廣到處理數(shù)據(jù)集中的所有國家。
        • 還可以將圖表擴展到另一個層次,以可視化各國的獎牌總數(shù)。

        NUM_COUNTRIES?=?5
        X_POS,?Y_POS?=?0.5,?1/(NUM_COUNTRIES-1)
        NODE_COLORS?=?["seagreen",?"dodgerblue",?"orange",?"palevioletred",?"darkcyan"]
        LINK_COLORS?=?["lightgreen",?"lightskyblue",?"bisque",?"pink",?"lightcyan"]

        source?=?[]
        node_x_pos,?node_y_pos?=?[],?[]
        node_labels,?node_colors?=?[],?NODE_COLORS[0:NUM_COUNTRIES]
        link_labels,?link_colors,?link_values?=?[],?[],?[]?

        #?第一組鏈接和節(jié)點
        for?i?in?range(NUM_COUNTRIES):
        ????source.extend([i]*3)
        ????node_x_pos.append(0.01)
        ????node_y_pos.append(round(i*Y_POS+0.01,2))
        ????country?=?df_medals['Country'][i]
        ????node_labels.append(country)?
        ????for?medal?in?["Gold",?"Silver",?"Bronze"]:
        ????????link_labels.append(f"{country}-{medal}")
        ????????link_values.append(df_medals[f"{medal}?Medals"][i])
        ????link_colors.extend([LINK_COLORS[i]]*3)

        source_last?=?max(source)+1
        target?=?[?source_last,?source_last+1,?source_last+2]?*?NUM_COUNTRIES
        target_last?=?max(target)+1

        node_labels.extend(["Gold",?"Silver",?"Bronze"])
        node_colors.extend(["gold",?"silver",?"brown"])
        node_x_pos.extend([X_POS,?X_POS,?X_POS])
        node_y_pos.extend([0.01,?0.5,?1])

        #?最后一組鏈接和節(jié)點
        source.extend([?source_last,?source_last+1,?source_last+2])
        target.extend([target_last]*3)
        node_labels.extend(["Total?Medals"])
        node_colors.extend(["grey"])
        node_x_pos.extend([X_POS+0.25])
        node_y_pos.extend([0.5])

        for?medal?in?["Gold","Silver","Bronze"]:
        ????link_labels.append(f"{medal}")
        ????link_values.append(df_medals[f"{medal}?Medals"][:i+1].sum())
        link_colors.extend(["gold",?"silver",?"brown"])

        print("node_labels",?node_labels)
        print("node_x_pos",?node_x_pos);?print("node_y_pos",?node_y_pos)

        node_labels?['United?States?of?America',?"People's?Republic?of?China",
        ????????????'Japan',?'Great?Britain',?'ROC',?'Gold',?'Silver',
        ????????????'Bronze',?'Total?Medals']
        node_x_pos?[0.01,?0.01,?0.01,?0.01,?0.01,?0.5,?0.5,?0.5,?0.75]
        node_y_pos?[0.01,?0.26,?0.51,?0.76,?1.01,?0.01,?0.5,?1,?0.5]
        #?顯示的圖
        NODES?=?dict(pad??=?20,?thickness?=?20,?
        ?????????????line?=?dict(color?=?"lightslategrey",
        ?????????????????????????width?=?0.5),
        ?????????????hovertemplate="?",
        ?????????????label?=?node_labels,?
        ?????????????color?=?node_colors,
        ?????????????x?=?node_x_pos,?
        ?????????????y?=?node_y_pos,?)
        LINKS?=?dict(source?=?source,?
        ?????????????target?=?target,?
        ?????????????value?=?link_values,?
        ?????????????label?=?link_labels,?
        ?????????????color?=?link_colors,
        ?????????????hovertemplate="%{label}",)
        data?=?go.Sankey(arrangement='snap',?
        ?????????????????node?=?NODES,?
        ?????????????????link?=?LINKS)
        fig?=?go.Figure(data)
        fig.update_traces(valueformat='3d',?
        ??????????????????valuesuffix='?Medals',?
        ??????????????????selector=dict(type='sankey'))
        fig.update_layout(title="Olympics?-?2021:?Country?&??Medals",??
        ??????????????????font_size=16,??
        ??????????????????width=1200,
        ??????????????????height=500,)
        fig.update_layout(hoverlabel=dict(bgcolor="grey",?
        ??????????????????????????????????font_size=14,?
        ??????????????????????????????????font_family="Rockwell"))
        fig.show("png")?



        延伸閱讀??

        延伸閱讀《利用Python進行數(shù)據(jù)分析》


        干貨直達??



        更多精彩??

        在公眾號對話框輸入以下關(guān)鍵詞
        查看更多優(yōu)質(zhì)內(nèi)容!

        讀書?|?書單?|?干貨?|?講明白?|?神操作?|?手把手
        大數(shù)據(jù)?|?云計算?|?數(shù)據(jù)庫?|?Python?|?爬蟲?|?可視化
        AI?|?人工智能?|?機器學習?|?深度學習?|?NLP
        5G?|?中臺?|?用戶畫像?|?數(shù)學?|?算法?|?數(shù)字孿生

        據(jù)統(tǒng)計,99%的大咖都關(guān)注了這個公眾號
        ??
        瀏覽 25
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            麻豆日逼视频 | 玉米地一级婬片A片 | 色色热热 | 婷婷被公交车猛烈进出 | 亚洲成人网站免费在线观看 | 特级a一级毛片免费观看 | 色色色色av | 欧美做爱视频网站视频 | 好多水h有妇之夫 | 少妇口述与子做过爱 |