Label text are inverted in the left half of Holoviews Chord plot

Hi, I have created a Holoviews Chord plot using some data and everything is fine. However the label texts in the left half of the chord getting inverted. I understand that the inner algorithm creates an angle for the nodes along with the labels which makes the labels inverted.
My client wants these labels in the left half not to get inverted. Is it possible to achieve this requirement somehow?

Would require a change in HoloViews or you would have to place the labels manually for now.

1 Like

Thanks for the response.
“place the label manually” - can it be done using hv.Labels?

Yes, and you’ll have to access the Chord.nodes and then compute sensible position and rotation values for each label. That said I’d be open to having an issue requesting the text rotation be fixed.

1 Like

Thank you so much. Really appreciate your suggestion. I will definitely try that out and I have also created an issue request here - Holoviews issue #4553

1 Like

@philippjfr Thanks for the suggestion. After using the hv.Labels with the nodes data I was able to fix the rotation of the label text in the chord plot.


I could not make the spacing uniformly because the text alignment options that are available in the opts.labels are either ‘left’, ‘right’ or ‘center’. But if it could take dictionary or expression as arguments for the text alignment then I can easily make left aligned text for the left half and right aligned text for the right half and that would look exactly as the original chord labels.

Full code for the same:

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’])
nodes = hv.Dataset(pd.DataFrame(data[‘nodes’]), ‘index’)

Creating chord without label text

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

label_data = chord.nodes.data.drop([‘index’], axis=1)

Assigning rotation value according to the node’s angle

label_data[‘rotation’] = np.arctan((label_data.y / label_data.x))

Moveing the label position little bit away from the nodes

label_data[‘y’] = label_data[‘y’].apply(lambda x: x * 1.3)
label_data[‘x’] = label_data[‘x’].apply(lambda x: x * 1.3)

Creating label element with node data

labels = hv.Labels(label_data)
labels.opts(
opts.Labels(cmap=‘magma’, text_font_size=‘10pt’, padding=0.08, angle= dim(‘rotation’) * 1260/22 ))

Merging chord with labels

chord * labels

1 Like