我尝试使用plotly绘制Sankey图,但得到的输出为空白,没有python或检查错误。
我创建的绘图类如下:
from typing import *
import logging
import pandas as pd
import plotly
import seaborn as sns
from .visualizer import AbstractVisualizer
class PlotlyVisualizer(AbstractVisualizer):
logger = logging.getLogger('PlotlyVisualizer')
def __init__(self, config: dict) -> None:
"""
Plotly Visualizer
"""
super().__init__(config=config)
@staticmethod
def __generate_sankey_figure__(nodes_df: pd.DataFrame, edges_df: pd.DataFrame, color_list: List,
title: str = 'Sankey Diagram'):
# creating the sankey diagram
data = dict(
type='sankey',
node=dict(
hoverinfo="all",
pad=15,
thickness=20,
line=dict(
color="black",
width=0.5
),
label=nodes_df['Node'],
color=color_list
),
link=dict(
source=edges_df['Source'],
target=edges_df['Target'],
value=edges_df['Count']
)
)
layout = dict(
title=title,
font=dict(
size=10
)
)
fig = dict(data=[data], layout=layout)
return fig
def plot(self, nodes_df: pd.DataFrame, edges_df: pd.DataFrame, attribute_cols: List, name_col: str):
# Generate color palette
color_palette = list(sns.color_palette(None, nodes_df.count()[0]).as_hex())
color_list = color_palette
fig = self.__generate_sankey_figure__(nodes_df=nodes_df, edges_df=edges_df, color_list=color_list,
title=self.__config__['plot_name'])
self.logger.info(fig)
filename = "{}/{}.html".format(self.__config__['target_path'], self.__config__['plot_name'])
plotly.offline.plot(fig, validate=True, filename=filename)
我用作输入的nodes_df和edges_df像这样:
nodes_df:
Node Count
0 New democracy_2019 158
1 New democracy_2007 153
2 Syriza_2015 149
3 Pasok_2007 102
4 Syriza_2019 86
5 New democracy_2015 77
6 Movement for change_2019 22
7 Kke_2007 22
8 Golden dawn_2015 17
9 The river_2015 17
10 Communist party of greece_2015 15
11 Communist party of greece_2019 15
12 Syriza_2007 14
13 Independent greeks_2015 13
14 Pasok-democratic alignment_2015 13
15 Laos_2007 10
16 Greek solution_2019 10
17 Mera25_2019 9
edges_df:
Source Target Count
0 New democracy_2015 New democracy_2019 28
1 New democracy_2007 New democracy_2015 22
2 Syriza_2015 Syriza_2019 18
3 New democracy_2007 New democracy_2019 16
4 Pasok_2007 Pasok-democratic alignment_2015 6
5 Pasok_2007 Movement for change_2019 4
6 Kke_2007 Communist party of greece_2019 3
7 Communist party of greece_2015 Communist party of greece_2019 2
8 Laos_2007 New democracy_2019 2
9 Pasok_2007 Syriza_2019 2
10 Pasok-democratic alignment_2015 Movement for change_2019 2
11 Syriza_2015 Mera25_2019 1
12 Syriza_2007 Syriza_2019 1
13 Syriza_2007 Syriza_2015 1
14 Pasok_2007 Syriza_2015 1
15 New democracy_2019 New democracy_2019 1
16 Pasok_2007 Mera25_2019 1
17 New democracy_2015 New democracy_2015 1
18 New democracy_2007 New democracy_2007 1
19 New democracy_2007 Independent greeks_2015 1
20 Laos_2007 New democracy_2015 1
21 Laos_2007 Greek solution_2019 1
22 The river_2015 New democracy_2019 1
最后,人物词典具有以下结构:
{'data':
[
{'type': 'sankey',
'node':
{'hoverinfo': 'all',
'pad': 15,
'thickness': 20,
'line':
{'color': 'black', 'width': 0.5},
'label': 0 New democracy_2019
1 New democracy_2007
2 Syriza_2015
3 Pasok_2007
4 Syriza_2019
5 New democracy_2015
6 Movement for change_2019
7 Kke_2007
8 Golden dawn_2015
9 The river_2015
10 Communist party of greece_2015
11 Communist party of greece_2019
12 Syriza_2007
13 Independent greeks_2015
14 Pasok-democratic alignment_2015
15 Laos_2007
16 Greek solution_2019
17 Mera25_2019
Name: Node, dtype: object,
'color': ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf', '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f']},
'link':
{'source': 0 New democracy_2015
1 New democracy_2007
2 Syriza_2015
3 New democracy_2007
4 Pasok_2007
5 Pasok_2007
6 Kke_2007
7 Communist party of greece_2015
8 Laos_2007
9 Pasok_2007
10 Pasok-democratic alignment_2015
11 Syriza_2015
12 Syriza_2007
13 Syriza_2007
14 Pasok_2007
15 New democracy_2019
16 Pasok_2007
17 New democracy_2015
18 New democracy_2007
19 New democracy_2007
20 Laos_2007
21 Laos_2007
22 The river_2015
Name: Source, dtype: object,
'target': 0 New democracy_2019
1 New democracy_2015
2 Syriza_2019
3 New democracy_2019
4 Pasok-democratic alignment_2015
5 Movement for change_2019
6 Communist party of greece_2019
7 Communist party of greece_2019
8 New democracy_2019
9 Syriza_2019
10 Movement for change_2019
11 Mera25_2019
12 Syriza_2019
13 Syriza_2015
14 Syriza_2015
15 New democracy_2019
16 Mera25_2019
17 New democracy_2015
18 New democracy_2007
19 Independent greeks_2015
20 New democracy_2015
21 Greek solution_2019
22 New democracy_2019
Name: Target, dtype: object,
'value': 0 28
1 22
2 18
3 16
4 6
5 4
6 3
7 2
8 2
9 2
10 2
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
Name: Count, dtype: int64}}],
'layout':
{'title': 'Sankey_2007_2015_2019',
'font': {'size': 10}}
}
如开头所述,在浏览器上我没有出现python错误,也没有检查错误,只是呈现了一个空白的html文件。
谢谢。
答案 0 :(得分:0)
我找到了解决方案。问题是edges_df
用其名称/标签而不是索引来表示每个节点。
只需对生成数据dict
的函数进行少量修改即可:
@staticmethod
def __generate_sankey_figure__(nodes_df: pd.DataFrame, edges_df: pd.DataFrame, color_list: List,
title: str = 'Sankey Diagram'):
# Create the node indices
nodes_list = nodes_df['Node'].tolist()
edges_df['SourceID'] = edges_df['Source'].apply(lambda x:
nodes_list.index(x))
edges_df['TargetID'] = edges_df['Target'].apply(lambda x:
nodes_list.index(x))
# creating the sankey diagram
data = dict(
type='sankey',
node=dict(
hoverinfo="all",
pad=15,
thickness=20,
line=dict(
color="black",
width=0.5
),
label=nodes_df['Node'],
color=color_list
),
link=dict(
source=edges_df['SourceID'],
target=edges_df['TargetID'],
value=edges_df['Count']
)
)
layout = dict(
title=title,
font=dict(
size=10
)
)
fig = dict(data=[data], layout=layout)
return fig