Creating chord diagram in Python
Asked Answered
S

2

0

I want to create a Chord diagram for the following dataset where I have the first two columns as physical locations and a third column showing how many people visited both.

Place1   Place2    Count
US       UK        200
FR       US        450
UK       US        200
NL       FR        150
IT       FR        500

I tried using Holoviews but I couldn't make it work

nodes = hv.Dataset(df, 'Place1', 'Place2')
chord = hv.Chord((df, nodes), ['Place1', 'Place2'], ['Count'])
graph = chord.select(selection_mode='nodes')

But I get the following error: DataError: None of the available storage backends were able to support the supplied data format.

How can I use this dataframe to create a Chord diagram?

Slipstream answered 27/11, 2020 at 0:6 Comment(0)
B
1

A possible solution to this is the following. Remember that your shared data is not very large and the resulting chord diagram is pretty uggly.

import holoviews as hv
chords = chord.groupby(by=["Place1", "Place2"]).sum()[["Count"]].reset_index()
chords = chords.sort_values(by="Count", ascending=False)

CChord = hv.Chord(chords)
print(CChord)
hv.extension("bokeh")
CChord

The last part hv.extension("bokeh") is essential for the visualization. You could even add label using something like this:

cities = list(set(chords["Place1"].unique().tolist() + chords["Place2"].unique().tolist()))
cities_dataset = hv.Dataset(pd.DataFrame(cities, columns=["City"]))

enter image description here

Burushaski answered 27/11, 2020 at 8:36 Comment(0)
O
1

The D3Blocks library can help create Chord charts and easily adjust the colors, weights, opacity, Font size. Let me illustrate it for your case:

Create your dataset:

import pandas as pd
import numpy as np

source=['US','FR','UK','NL','IT']
target=['UK','US','US','FR','FR']
weights=[200,450,200,150,500]

df = pd.DataFrame(data=np.c_[source, target, weights], columns=['source','target','weight'])

Now we can create the Chord chart:

pip install d3blocks

# Import library
from d3blocks import D3Blocks    
# Initialize
d3 = D3Blocks(frame=False)
d3.chord(df, color='source', opacity='source', cmap='Set2')

We can also make adjustments:

# Edit any of the properties you want in the dataframe:
d3.node_properties
d3.node_properties.get('NL')['color']='#000000'
# {'US': {'id': 0, 'label': 'US', 'color': '#1f77b4', 'opacity': 0.8},
#  'UK': {'id': 1, 'label': 'UK', 'color': '#98df8a', 'opacity': 0.8},
#  'FR': {'id': 2, 'label': 'FR', 'color': '#8c564b', 'opacity': 0.8},
#  'NL': {'id': 3, 'label': 'NL', 'color': '#000000', 'opacity': 0.8},
#  'IT': {'id': 4, 'label': 'IT', 'color': '#9edae5', 'opacity': 0.8}}

d3.edge_properties
d3.edge_properties[('FR', 'US')]['color']='#000000'

# {('FR', 'US'): {'source': 'FR',
#   'target': 'US',
#   'weight': 450.0,
#   'opacity': 0.8,
#   'color': '#8c564b'},
#  ('IT', 'FR'): {'source': 'IT',
#   'target': 'FR',
#   'weight': 500.0,
#   'opacity': 0.8,
#   ...
#   ...

# Plot again
d3.show()

enter image description here

Oviform answered 11/11, 2022 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.