摘要:由此觀之,實現桑基圖的核心在于計算出以上的這些點坐標。減少邊交叉當數據量到一定程度的時候,桑基圖中的邊會出現重疊現象,造成一定的視覺混亂。綜上,桑基圖是一個展現數據流非常好用的視圖,感興趣的同學可以自己實現一個試試。
原文地址:https://geekplux.com/2018/08/28/how-to-implement-sankey-diagram.html什么是桑基圖
Google 搜索桑基圖,可以搜到一大堆定義。簡而言之,桑基圖是一種數據流圖,展示了數據是如何從左到右流向最后的節點,每條邊代表一條數據流,寬度代表數據流的大小。桑基圖常用于流量分析,可以很清楚的看出數據是如何漸漸分流的。本文著重講解如何實現,理論方面的東西各位可以自行了解。
實現桑基圖的關鍵點關鍵點有兩個:
1. 坐標計算桑基圖要展現的數據流,算是圖(拓撲類、網絡型或關系型)數據的一種。實現一個數據可視化圖,最重要的就是拆解元素。而實現一個圖數據可視化,則最重要的是分清“節點”和“邊”。
拆解元素之后,最重要的便是坐標的計算,這里包括點和邊的坐標。而圖形中,任何的元素都可以看作是點連線而成,所以元素坐標的計算實際上就成了點坐標的計算。比如桑基圖中,節點是一個矩形,那么只需計算兩個點(左上和右下)的坐標(x0, y0),(x1, y1)便可確定;邊是一個帶形,需要計算四個端點才能確定,帶形的弧度則可由簡單的三次貝塞爾曲線計算得來。
由此觀之,實現桑基圖的核心在于計算出以上的這些點坐標。其實實現任意一種可視化都是計算點的坐標。
2. 減少邊交叉當數據量到一定程度的時候, 桑基圖中的邊會出現重疊現象,造成一定的視覺混亂。如何減少可以閱讀本文第二節。
一、坐標計算的實現 準備工作 設計數據結構經典的圖數據結構一般是鄰接矩陣和鄰接表,我們也可以自己設計。我在做拓撲數據可視化的時候,會先和后端或數據同學商定好我需要拿到的數據結構,通常是這個樣子:
{ nodes: [ { foo: bar }, { foo: baz }, ... ], links: [ { source: 0, target: 1, value: 100 }, { source: 1, target: 2, value: 10 }, ... ] }
而我拿到之后要做的第一步就是先把 nodes 和 links 串聯起來,這里每個 link 的 source 和 target 分別是 nodes 的下標,當然你也可以設置其他的引用(指針),總之通過引用講兩者串聯起來,變成:
{ nodes: [ { foo: bar, column: 0, // 節點所在第幾列 row: 0, // 節點所在第幾行 value: 100, // 節點數據流大小 sourceLinks: [ { source: 0, target: 1, ... } ], targetLinks: [ ... ] }, ... ], links: [ { source: 0, target: 1, value: 100, sourceNode: { foo: bar, column: 0, row: 0, ... }, targetNode: { ... } }, ... ] }
這樣,對于某個節點來說,可以直接用 O(1) 的時間復雜度訪問到它的任意相鄰節點。
計算節點數據流大小這里的計算方法可自己定,通常是取該節點入邊和出邊的數據流大小之和的最小值。
計算節點所在行列在桑基圖的計算中,我們還需要進行一個關鍵的計算——計算節點在桑基圖中的第幾行第幾列。
第幾列的計算,即為節點在圖中的深度計算:
入度為 0 的節點深度為 0,在第一列
出度為 0 的節點深度最大,在最后一列
其余節點的深度為他相連源節點的最大深度加 1
第幾行的計算,涉及到排序的問題,通常某一列中的節點都是按節點數據流大小,從大到小排序。
節點坐標計算剛才我們說過,坐標計算可以分為兩部分:節點和邊。其中,邊的坐標位置依賴于節點的坐標,所以應該先計算節點坐標。
但在計算坐標之前,首先要明確一個問題:是否限定視圖的寬高。這個問題引申出兩種節點坐標的計算方式。
不限定視圖寬高如果不限定寬高,那么節點坐標的計算步驟很簡單:
設置一個節點的寬度
設置節點的水平間距
從左至右,根據剛才計算出的節點所在第幾列,計算出節點的橫坐標(x0, x1),初始的 x0 為 0
設定一個比例尺函數(多大的數據流對應屏幕上的多少像素,通常是首先設定一個節點最小高度和一個節點最大高度,然后找出所有節點數據流的最小和最大值,映射成一個定義域為節點數據流大小,值域為節點高度的函數)
通過比例尺計算出節點高度
設置一個節點垂直間距
從上至下,根據剛才計算出的節點所在第幾行,計算出節點的縱坐標 (y0, y1),初始的 y0 為 0
大致是這個思路,橫坐標的計算取決于兩個值,節點寬度和 節點水平間距;縱坐標的計算取決于 節點的數據流大小 和 節點垂直間距。
具體的計算代碼,可根據你自己的數據結構來調整。
限定視圖寬高如果限定寬高,那么計算步驟需要換個思路:
節點的寬度和節點的水平間距需要根據節點的列數和視圖寬度來計算,你可以自己手動調整也可以設計個算法來算
從左只有,根據節點寬度和節點水平間距,計算出節點橫坐標
設定一個比例尺函數,計算出節點的高度
設置一個節點垂直間距
通過高斯-賽德爾迭代(Gauss–Seidel method)計算出縱坐標(大致的思路是,先根據前兩步的數值算出一個初始節點坐標,如果總體布局超出視圖的下界,則節點高度和節點垂直間距都按比例縮小(如 0.95),并同時上移 n 個像素,如果總體布局超出視圖上界,則節點高度和垂直間距都按比例縮小,并同時下移 n 個像素,直到總體的桑基圖布局適應一開始限定的視圖寬高)
這個思路是 d3-sankey 的實現思路。如果你有限定視圖寬高的需求,那么可以直接使用 d3-sankey。
邊的坐標計算只要確定了節點坐標,邊的坐標可以根據它源節點和目標節點的坐標來算出:
對于一個節點,將它的出邊和入邊進行排序(排序方法通常是根據相連節點在第幾行從上到下排,也可以通過一些其他排序方法減少邊的交叉,具體在第二節介紹)
計算每個節點中單位數據流占節點高度的比例
根據出邊入邊的數據流大小,乘上一步計算出的比例,則可得到每條邊左右兩邊的高度
從上到下,計算每條邊的縱坐標
每條邊四個端點的橫坐標分別對應源節點和目標節點的橫坐標
以上操作可以通過遍歷每個 node 的 sourceLinks 和 targetLinks 來計算。得到邊的四個端點以后,就可以算出三次貝塞爾曲線的控制點了:
二、如何減少交叉通常要減少邊的交叉,可以采用下面兩種方法:
均值排序
sugiyama 算法
均值排序這個名字是我自己起的。。不過這個方法很實用有效。
對于每個源節點來說,都有相連的目標節點。這里的“均值”指的是所有相連目標節點所在行數的平均值(所有目標節點的行數相加,除以目標節點個數),這個平均值可以大致描述該節點每個出邊的位置。每條出邊都有這樣一個值,這個值越小,則說明該出邊要連接的目標節點的位置越靠上,反之越靠下。所以可根據這個值,從小到大排出出邊在該節點上從上到下的位置。
三、具體項目中的交互我參與的 UBA (User Behavior Analytics 內部項目) 項目中,正好用到了桑基圖。除了上述的圖形繪制之外,主要復雜的是交互。
如圖所示,除了基本的 hover 交互之外,項目中主要還有
minimap 拖拽和刷選
主視圖的拖拽和縮放
左下角的過濾器
點擊交互,高亮只經過選中節點的路徑,并且邊上高亮的部分由最后一個選中節點懈怠的數據流值確定,其余部分半透明
整個桑基圖實現下來發現繪制只是一些計算,交互才是更難抽象和處理的部分。
綜上,桑基圖是一個 展現數據流非常好用的視圖,感興趣的同學可以自己實現一個試試。除了我文章中這些基本的桑基圖布局,你還可以試試其他變種,另外交互方面也可以突破剛才我提到的那些,比如我之前實現過點擊節點進行折疊/展開的交互。總體來說可視化還是一個比較有意思的方向。
本作品采用知識共享 署名-非商業性使用-禁止演繹 4.0 國際 許可協議進行許可。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100332.html
Python pyecharts可以繪制的圖形還是比較的多的,比如可以用來可以繪制各種各樣的圖形,應用到多種不同的場合,那么,怎么用Python pyecharts去繪制基圖呢?怎么快速的去繪制呢?下面就給大家詳細解答下。 桑基圖 桑基圖(Sankey diagram),即桑基能量分流圖,也叫桑基能量平衡圖。它是一種特定類型的流程圖,圖中延伸的分支的寬度對應數據流量的大小,通常應用于能源、...
摘要:概述我非常認同前百度數據工程師現神策分析創始人桑老師最近談到的數據分析三重境界統計計數多維分析機器學習數據分析的統計計數和多維分析,我們通常稱之為數據探索式分析,這個步驟旨在了解數據的特性,有助于我們進一步挖掘數據的價值。 showImg(https://camo.githubusercontent.com/f98421e503a81176b003ddd310d97e1e1214625...
摘要:這些功能和詞匯聽起來非常復雜,似乎對業務人員要求很高,但像網易有數這樣的敏捷可視化分析工具不僅具備這樣的能力,而且易學易用,業務人員只需簡單拖拽,就能輕松制作出兼具敏捷分析與精美展示的報告。 歡迎訪問網易云社區,了解更多網易技術產品運營經驗。 在回答小企業是否需要數據分析這個問題之前,不妨先想想下面兩個問題: 你在電腦上建過表格嗎? 你基于表格中的數據畫過柱形圖、餅狀圖、折線圖嗎? 可...
摘要:概述是一個基于和的數據可視化分析包,適用于圖表,制作。目前支持的組件主依賴安裝使用建議使用搭建環境,以下只針對標準環境。圖及其他圖標支持的數據類型請見項目主頁。 Vs 概述 Vs 是一個基于 d3.js 和 vue.js 的數據可視化分析包,適用于圖表,dashboard 制作。 Github Repo 目前支持的組件 d3Bar d3Line d3Pie d3ProgressArc...
摘要:徐盛測試中心總監。移動互聯的到來給測試帶來了哪些挑戰徐盛開發移動應用確實給我們的開發和測試人員都帶來了新的挑戰。測試管理的難點在哪幾個方面徐盛測試管理在項目級別和組織級別各有不同的難點。 2016年7月22日,「HPE&msup軟件技術開放日」將在上海浦東新區,張江高科技園區納賢路799號科榮大廈小樓2樓舉辦,msup攜手HPE揭秘全球測試中心背后的12條技術實踐。 徐盛:HPE測試中...
閱讀 2604·2021-11-02 14:39
閱讀 4322·2021-10-11 10:58
閱讀 1446·2021-09-06 15:12
閱讀 1837·2021-09-01 10:49
閱讀 1326·2019-08-29 18:31
閱讀 1882·2019-08-29 16:10
閱讀 3331·2019-08-28 18:21
閱讀 867·2019-08-26 10:42