【问题标题】:How can we create a Chord Diagram with a dataframe object?我们如何使用数据框对象创建和弦图?
【发布时间】:2022-01-10 07:21:05
【问题描述】:

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

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 dataframe,'nodes'是holoviews数据集,类型是这样的。

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

所以,我的问题是……如何将数据框输入到和弦图中?这是我的示例数据框。另外,我不知道如何将 合并到组合中。

【问题讨论】:

    标签: python python-3.x chord-diagram


    【解决方案1】:

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

    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。

    【讨论】:

    • 非常感谢!!正是我想要的!!!!
    • 再次感谢。这是将标签转换为分类值的另一种方法。 df_fin = pd.DataFrame({col: df[col].astype('category').cat.codes for col in df}, index=df.index) df_fin
    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2018-12-03
    • 2020-02-27
    • 2019-07-11
    • 1970-01-01
    相关资源
    最近更新 更多