我们如何使用数据框对象创建和弦图?

How can we create a Chord Diagram with a dataframe object?

我在网上找到了这个通用代码。

import pandas as pd
import holoviews as hv
from holoviews import opts, dim
from bokeh.sampledata.les_mis import data

hv.extension('bokeh')
hv.output(size=200)

links = pd.DataFrame(data['links'])
print(links.head(3))
hv.Chord(links)

nodes = hv.Dataset(pd.DataFrame(data['nodes']), 'index')
nodes.data.head()

chord = hv.Chord((links, nodes)).select(value=(5, None))
chord.opts(
    opts.Chord(cmap='Category20', edge_cmap='Category20', edge_color=dim('source').str(), 
               labels='name', node_color=dim('index').str()))

就是这样,看起来不错。

[![在此处输入图片描述][1]][1]

示例数据来自此处。

https://holoviews.org/reference/elements/bokeh/Chord.html

显然,'links'是一个pandas数据框,'nodes'是一个全息图数据集,类型是这样的。

<class 'pandas.core.frame.DataFrame'>
<class 'holoviews.core.data.Dataset'>

所以,我的问题是...如何将数据框输入和弦图?这是我的示例数据框。另外,我不知道如何将 融入其中。

我认为您的数据不符合该功能的要求。让我解释一下为什么我这么认为?

Chord-函数期望至少在数据集(这可以是一个 pandas DataFrame)上有三列,但所有元素都是数字。

   source  target  value
0       1       0      1
1       2       0      8
2       3       0     10

第二个数据集是可选的。例如,这可以在第二列中使用字符串来添加标签。

    index     name  group
0      0         a      0
1      1         b      0
2      2         c      0

基本示例

您给定的数据如下所示。

    Measure     Country Value
0   Arrivals    Greece  1590
1   Arrivals    Spain   1455
2   Arrivals    France  1345
3   Arrivals    Iceland 1100
4   Arrivals    Iceland 1850
5   Departures  America 2100
6   Departures  Ireland 1000
7   Departures  America 950
8   Departures  Ireland 1200
9   Departures  Japan   1050

如果您将 DataFrame df 中的字符串替换为这样的数字,您可以使用基本形式输入日期:

_df = df.copy()
values = list(_df.Measure.unique())+list(_df.Country.unique())
d = {value: i for i, value in enumerate(values)}

def str2num(s):
    return d[s]

_df.Measure = _df.Measure.apply(str2num)
_df.Country = _df.Country.apply(str2num)

>>> df
    Measure Country Value
0   0   2   1590
1   0   3   1455
2   0   4   1345
3   0   5   1100
4   0   5   1850
5   1   6   2100
6   1   7   1000
7   1   6   950
8   1   7   1200
9   1   8   1050

现在你的数据符合基本条件,你可以创建弦图了。

chord = hv.Chord(_df).select(value=(5, None))
chord.opts(
    opts.Chord(cmap='Category20', edge_cmap='Category20', 
               edge_color=dim('Measure').str(), 
               labels='Country', 
               node_color=dim('index').str()))

如你所见,所有的连接线只有两种颜色中的一种。这是因为 Measure 列中只有两个元素。所以我想,这不是你想要的。

修改示例

让我们稍微修改一下您的数据:

_list = list(df.Country.values)
new_df = pd.DataFrame({'From':_list, 'To':_list[3:]+_list[:3], 'Value':df.Value})
>>> new_df
       From      To Value
0    Greece Iceland  1590
1     Spain Iceland  1455
2    France America  1345
3   Iceland Ireland  1100
4   Iceland America  1850
5   America Ireland  2100
6   Ireland   Japan  1000
7   America  Greece   950
8   Ireland   Spain  1200
9     Japan  France  1050

和:

node = pd.DataFrame()
for i, value in enumerate(df.Measure.unique()):
    _list = list(df[df['Measure']==value].Country.unique())
    node = pd.concat([node, pd.DataFrame({'Name':_list, 'Group':i})], ignore_index=True)
>>> node
    Name    Group
0   Greece  0
1   Spain   0
2   France  0
3   Iceland 0
4   America 1
5   Ireland 1
6   Japan   1

现在我们必须再次替换 new_df 中的字符串,然后才能再次调用 Chord 函数。

values = list(df.Country.unique())
d = {value: i for i, value in enumerate(values)}

def str2num(s):
    return d[s]

new_df.From = new_df.From.apply(str2num)
new_df.To = new_df.To.apply(str2num)

hv.Chord(new_df)
nodes = hv.Dataset(pd.DataFrame(node), 'index')
chord = hv.Chord((new_df, nodes)).select(value=(5, None))
chord.opts(
    opts.Chord(cmap='Category20', edge_cmap='Category20', edge_color=dim('From').str(), 
               labels='Name', node_color=dim('index').str()
              )
)

现在有两个组添加到 HoverTool。