Oft brauchen wir eine Situation, in der wir visualisieren müssen, wie Daten zwischen Entitäten fließen. Nehmen wir zum Beispiel, wie Einwohner von einem Land in ein anderes ziehen. Hier ist eine Demonstration, wie viele Einwohner von England nach Nordirland, Schottland und Wales gezogen sind.
Aus dieser Sankey-Visualisierung geht klar hervor, dass mehr Einwohner von England nach Wales gezogen sind als aus Schottland oder Nordirland.
Sankey-Diagramme stellen normalerweise den Datenfluss von einer Entität (oder einem Knoten) zu einer anderen Entität (oder einem anderen Knoten) dar.
Die Entitäten, zu denen Daten fließen, werden als Knoten bezeichnet. Der Knoten, von dem der Datenfluss ausgeht, ist der Quellknoten (z. B. England auf der linken Seite), und der Knoten, an dem der Datenfluss endet, ist der Zielknoten (z. B. Wales auf der rechten Seite). ). Quell- und Zielknoten werden normalerweise als beschriftete Rechtecke dargestellt.
Der Fluss selbst wird durch gerade oder gekrümmte Pfade, sogenannte Links, dargestellt. Die Breite eines Streams/Links ist direkt proportional zur Lautstärke/Anzahl der Streams. Im obigen Beispiel ist die Bewegung von England nach Wales (d. h. die Migration von Einwohnern) umfangreicher (d. h. die Migration von Einwohnern) als die Bewegung von England nach Schottland oder Nordirland (d. h. die Migration von Einwohnern), was darauf hindeutet, dass mehr Einwohner Ziehen Sie lieber nach Wales als in andere Länder.
Sankey-Diagramme können verwendet werden, um den Fluss von Energie, Geld, Kosten und allem anderen mit einem Flusskonzept darzustellen.
Minards klassische Karte von Napoleons Invasion in Russland ist wahrscheinlich das berühmteste Beispiel einer Sankey-Karte. Diese Visualisierung mithilfe eines Sankey-Diagramms zeigt sehr effektiv, wie die französische Armee auf ihrem Weg nach Russland und zurück vorankam (oder abnahm?).
In diesem Artikel verwenden wir Pythons Plotly, um ein Sankey-Diagramm zu zeichnen.
In diesem Artikel wird der Datensatz der Olympischen Spiele 2021 verwendet, um ein Sankey-Diagramm zu zeichnen. Der Datensatz enthält detaillierte Informationen über die Gesamtzahl der Medaillen – Land, Gesamtzahl der Medaillen und individuelle Gesamtzahlen für Gold-, Silber- und Bronzemedaillen. Wir erstellen ein Sankey-Diagramm, um herauszufinden, wie viele Gold-, Silber- und Bronzemedaillen ein Land gewonnen hat.
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 CountDtype --------- ------------------- 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 Total93 non-null int64 6 Rank by Total93 non-null int64 7 Unnamed: 7 0 non-nullfloat64 8 Unnamed: 8 1 non-nullfloat64 dtypes: float64(2), int64(6), object(1) memory usage: 6.7+ KB None
Verwenden Sie plotlys go.Sankey. Diese Methode benötigt 2 Parameter – Knoten und Links (Knoten und Links).
Hinweis: Alle Knoten – Quelle und Ziel – sollten eindeutige Kennungen haben.
Im Fall des olympischen Medaillendatensatzes dieses Artikels:
Quelle ist das Land. Betrachten Sie die ersten drei Länder (USA, China und Japan) als Quellknoten. Beschriften Sie diese Quellknoten mit den folgenden (eindeutigen) Kennungen, Bezeichnungen und Farben:
Ziel ist Gold, Silber oder Bronzemedaille. Beschriften Sie diese Zielknoten mit den folgenden (eindeutigen) Bezeichnern, Beschriftungen und Farben:
Link (Quellknoten und Zielknoten) ist die Anzahl der Medaillen jeder Art. In jeder Quelle gibt es 3 Links, die jeweils mit einem Ziel enden – Gold, Silber und Bronze. Insgesamt gibt es also 9 Links. Die Breite jedes Glieds sollte der Anzahl der Gold-, Silber- und Bronzemedaillen entsprechen. Beschriften Sie diese Links zu Zielen, Werten und Farben mit den folgenden Quellen:
Erfordert die Instanziierung von 2 Python-Diktobjekten zur Darstellung von
und an plotly’s go.Sankey übergeben.
Jeder Index der Liste (Beschriftung, Quelle, Ziel, Wert und Farbe) entspricht einem Knoten oder Link.
NODES = dict( # 0 1 23 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], # 链接的起点或源节点 target = [3,4,5,3,4,5,3,4,5], # 链接的目的地或目标节点 value =[ 39, 41, 33, 38, 32, 18, 27, 14, 17], # 链接的宽度(数量) # 链接的颜色 # 目标节点: 3-Gold4-Silver5-Bronze color = [ "lightgreen", "lightgreen", "lightgreen",# 源节点:0 - 美国 States of America "lightskyblue", "lightskyblue", "lightskyblue",# 源节点:1 - 中华人民共和国China "bisque", "bisque", "bisque"],)# 源节点:2 - 日本 data = go.Sankey(node = NODES, link = LINKS) fig = go.Figure(data) fig.show()
Dies ist ein sehr einfaches Sankey-Diagramm. Aber ist Ihnen schon einmal aufgefallen, dass das Diagramm zu breit ist und die Silbermedaillen vor den Goldmedaillen erscheinen?
So passen Sie die Position und Breite der Knoten an.
X- und Y-Positionen für Knoten hinzufügen, um die Position des Knotens explizit anzugeben. Der Wert sollte zwischen 0 und 1 liegen.
NODES = dict( # 0 1 23 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()
Also haben wir ein kompaktes Sankey-Diagramm erhalten:
Werfen wir einen Blick darauf, wie die verschiedenen im Code übergebenen Parameter den Knoten und Links im Diagramm zugeordnet werden.
代码如何映射到桑基图
我们都知道plotly绘图是交互的,我们可以将鼠标悬停在节点和链接上以获取更多信息。
带有默认悬停标签的桑基图
当将鼠标悬停在图上,将会显示详细信息。悬停标签中显示的信息是默认文本:节点、节点名称、传入流数、传出流数和总值。
例如:
如果我们觉得这些标签太冗长了,我们可以对此进程改进。使用hovertemplate参数改进悬停标签的格式
NODES = dict( # 0 1 23 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], # 链接的起点或源节点 target = [3,4,5,3,4,5,3,4,5], # 链接的目的地或目标节点 value =[ 39, 41, 33, 38, 32, 18, 27, 14, 17], # 链接的宽度(数量) # 链接的颜色 # 目标节点:3-Gold4 -Silver5-Bronze color = ["lightgreen", "lightgreen", "lightgreen", # 源节点:0 - 美国 "lightskyblue", "lightskyblue", "lightskyblue", # 源节点:1 - 中国 "bisque", "bisque", "bisque"],# 源节点: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()
带有改进的悬停标签的桑基图
对多个节点和级别进行泛化相对于链接,节点被称为源和目标。作为一个链接目标的节点可以是另一个链接的源。
该代码可以推广到处理数据集中的所有国家。
还可以将图表扩展到另一个层次,以可视化各国的奖牌总数。
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 = [], [], [] # 第一组链接和节点 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]) # 最后一组链接和节点 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")
Das obige ist der detaillierte Inhalt vonPython zeichnet atemberaubende Sankey-Diagramme. Haben Sie es gelernt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!