Search code examples
holoviews

How to use colors in a Chord diagram based on rgb values stored in a dict


I'm trying to change the colors of the arcs in a Chord diagram based on rgb values stored in a dictionary. I'm using HoloViews. The following code creates a Chord diagram and uses the 'Category20' palette group;

    import pandas as pd
    import numpy as np
    from holoviews import opts, dim
    import holoviews as hv
    hv.extension('bokeh')
    hv.output(size=200)

    my_dict = {'khaki': {'khaki': 21, 'mediumslateblue': 22, 'lightgreen': 15, 'lightcoral': 13}, 'mediumslateblue': {'khaki': 23, 'mediumslateblue': 13, 'lightgreen': 4, 'lightcoral': 21}, 'lightgreen': {'khaki': 23, 'mediumslateblue': 16, 'lightgreen': 10, 'lightcoral': 9}, 'lightcoral': {'khaki': 4, 'mediumslateblue': 10, 'lightgreen': 29, 'lightcoral': 9}}
    color_dict = {'Color': {0: '(252, 255, 104)', 1: '(104, 107, 255)', 2: '(104, 255, 119)', 3: '(255, 104, 129)'}, 'ColorName': {0: 'khaki', 1: 'mediumslateblue', 2: 'lightgreen', 3: 'lightcoral'}}

    df = pd.DataFrame(my_dict)
    df_colors = pd.DataFrame(color_dict)
    print(df)
    print(df_colors)
    data = hv.Dataset((list(df.columns), list(df.index), df),['source', 'target'], 'value').dframe()

    chord=hv.Chord(data)

    chord.opts(
        opts.Chord(cmap='Category20', edge_cmap='Category20', edge_color=dim('source').str(), 
                   label_index='index', node_color=dim('index').str()))

enter image description here

However, I want to use colors that are defined in my 'color_dict' dictionary. If I convert this dictionary to a dataframe it looks like this;

             Color        ColorName
0  (252, 255, 104)            khaki
1  (104, 107, 255)  mediumslateblue
2  (104, 255, 119)       lightgreen
3  (255, 104, 129)       lightcoral

The dataframe that I use to create the Chord diagram uses the 'ColorName' as column names and index labels;

                       khaki  mediumslateblue  lightgreen  lightcoral
    khaki               21               23          23           4
    mediumslateblue     22               13          16          10
    lightgreen          15                4          10          29
    lightcoral          13               21           9           9


Is it possible to use this dictionary to define the colors of the arcs in the Chord diagram?


Solution

  • Great that you use chord diagrams. The docs say it:

    You can make your own custom colormaps by providing a list of hex colors:
    img.options(cmap=['#0000ff', '#8888ff', '#ffffff', '#ff8888', '#ff0000'], colorbar=True, width=400)

    Convert your dict to a list of hex colors:

    import webcolors
    
    color_dict = {'Color': {0: (252, 255, 104), 1: (104, 107, 255), 2: (104, 255, 119), 3: (255, 104, 129)}}
    
    color_lst = [rgb for item in color_dict.values() for rgb in item.values()]
    color_lst = [webcolors.rgb_to_hex(rgb) for rgb in color_lst]
    

    And then set cmap=color_lst:

    chord.opts(opts.Chord(cmap=color_lst, edge_cmap='Category20', edge_color=dim('source').str(), label_index='index', node_color=dim('index').str()))