我正在使用 go.Plotly 尝试让节点按特定顺序输出。我希望它匹配mapping_dict顺序,或者至少使每个节点的类别保持相同的顺序。
我看过相关问题,但它们的初始结构不同,所以我不认为这是重复。如果没有请告诉我!
目标是按照 A、B、C、D、E 顺序进行(如果缺少其中之一,仍保持相同的顺序)。
函数调用 图=plot_sankey(links_dict,unique_source_targets,mapping_dict,颜色=颜色) 样本数据 映射_字典 = {'B_round1': 0, 'C_round1': 1, 'D_round1': 2, 'E_round1': 3, 'A_round2': 4, 'B_round2': 5, 'C_round2': 6, 'D_round2': 7, 'E_round2': 8, 'A_round3': 9, 'B_round3': 10, 'C_round3': 11, 'D_round3': 12, ‘E_round3’:13}
unique_source_targets=['B_round1', 'C_round1', 'D_round1', 'E_round1', 'A_round2', 'B_round2', 'C_round2', 'D_round2', 'E_round2', 'A_round3', 'B_round3', 'C_round3', 'D_round3', 'E_round3']
links_dict = {'来源': [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4 , 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8], '目标': [4 , 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 9, 10, 9, 10, 11, 12 , 13, 9, 10, 11, 12, 13, 9, 10, 11, 12, 13, 9, 10, 11, 12, 13], '值': [1433, 2761, 521, 205, 117, 239 , 472, 122, 61, 31, 282, 222, 81, 71, 77, 276, 59, 41, 60, 161, 2224, 6, 548, 2449, 371, 110, 36, 155, 482, 80, 34 , 14, 105, 164, 52, 46, 30, 175, 47, 23, 37, 104]}
代码
def plot_sankey(
links_dict,
unique_source_targets,
mapping_dict,
colors=None,
fig_title='Sankey Diagram',
subtitle=''):
# Generate formatted labels using a compute_round_labels function, which produces the label name then (value, percentage)
formatted_labels = compute_round_labels(links_dict, unique_source_targets, mapping_dict)
# Convert the unique_source_target list into the formatted labels for display
display_labels = [formatted_labels[label] for label in unique_source_targets]
fig = go.Figure(
data=[
go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color="black", width=0.5),
label=display_labels,
color=(colors if colors else "blue"),
),
link=dict(
source=links_dict["source"],
target=links_dict["target"],
value=links_dict["value"],
),
)
]
)
# Setting the title with the subtitle using HTML formatting
full_title = f'{fig_title}<br><sub>{subtitle}</sub>'
fig.update_layout(title_text=full_title, font_size=20)
# Adjusting layout margin to accommodate title and subtitle
fig.update_layout(
margin=dict(t=100) # Top margin; increase if title and subtitle are clipped
)
return fig
基本上,你几乎是对的。您必须在桑基图中强制执行特定的节点顺序,因此您需要确保
links_dict
中源节点和目标节点的索引与 mapping_dict
中指定的所需出现顺序一致。这是一种方法。您需要自己添加这些值
import plotly.graph_objects as go
import pandas as pd
def plot_sankey(links_dict, unique_source_targets, mapping_dict, colors=None, fig_title='Sankey Diagram', subtitle=''):
custom_order = ['A', 'B', 'C', 'D', 'E']
sorted_items = sorted(mapping_dict.items(), key=lambda x: (x[0][-7:], custom_order.index(x[0][0])))
mapping_dict = {item[0]: i for i, item in enumerate(sorted_items)}
links_dict['source'] = [mapping_dict[unique_source_targets[x]] for x in links_dict['source']]
links_dict['target'] = [mapping_dict[unique_source_targets[x]] for x in links_dict['target']]
display_labels = [x.split('_')[0] + ' round' + x[-1] for x in unique_source_targets] # Simplified label generation for example
fig = go.Figure(data=[
go.Sankey(
node=dict(
pad=15, thickness=20,
line=dict(color="black", width=0.5),
label=display_labels,
color=colors if colors else ["blue"]*len(display_labels),
),
link=dict(
source=links_dict['source'],
target=links_dict['target'],
value=links_dict['value']
)
)
])
full_title = f'{fig_title}<br><sub>{subtitle}</sub>'
fig.update_layout(title_text=full_title, font_size=20)
fig.update_layout(margin=dict(t=100))
return fig
mapping_dict = {'B_round1': 0, 'C_round1': 1, 'D_round1': 2, 'E_round1': 3, 'A_round2': 4, 'B_round2': 5,
'C_round2': 6, 'D_round2': 7, 'E_round2': 8, 'A_round3': 9, 'B_round3': 10, 'C_round3': 11,
'D_round3': 12, 'E_round3': 13}
unique_source_targets = list(mapping_dict.keys())
links_dict = {
'source': [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8],
'target': [4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 9, 10, 9, 10, 11, 12, 13, 9, 10, 11, 12, 13, 9, 10, 11, 12, 13, 9, 10, 11, 12, 13],
'value': [1433, 2761, 521, 205, 117, 239, 472, 122, 61, 31, 282, 222, 81, 71, 77, 276, 59, 41, 60, 161, 2224, 6, 548, 2449, 371, 110, 36, 155, 482, 80, 34, 14, 105, 164, 52, 46, 30, 175, 47, 23, 37, 104]
}
fig = plot_sankey(links_dict, unique_source_targets, mapping_dict, colors=['red', 'blue']*7)
fig.show()