Search code examples
pythonbokehbokehjs

How to add label in each line using Bokeh


I was trying to create a close area using Bokeh. That is how I have done that,

from bokeh.plotting import figure, output_file, show

p = figure(title="line", plot_width=300, plot_height=300)
p.line([1, 2, 3, 4, 5, 1], [6, 7, 8, 7, 3, 6])      
p.scatter([1, 2, 3, 4, 5, 1], [6, 7, 8, 7, 3, 6])


show(p)

Now I want to find out the length of each line using this function:

def distance(x1, y1, x2, y2):
    # compute cartesian distance
    return np.sqrt((x1-x2)**2 + (y1-y2)**2)

want to attach the information in each line as a line label. I am having difficulties. Can somebody please help.

here is my bokeh plotting:

enter image description here

However,I want to achieve something like this with proper labeling:

enter image description here

I will be so grateful if someone helps me to achieve this.


Solution

  • Need some more fine-tuning -

    import numpy as np
    from bokeh.plotting import figure, output_file, show
    from bokeh.models import ColumnDataSource, Label, LabelSet, Range1d
    
    p = figure(title="line", plot_width=300, plot_height=300)
    x = [1, 2, 3, 4, 5, 1]
    y = [6, 7, 8, 7, 3, 6]
    
    def distance(x1, y1, x2, y2):
        # compute cartesian distance
        return np.sqrt((x1-x2)**2 + (y1-y2)**2)
    
    dist = []
    x_mid = []
    y_mid = []
    
    for i in range(0,len(x)-1):
        if (i != len(x)-1):
            dist1 = round(distance(x[i],y[i],x[i+1],y[i+1]),2)
            x_mid1 = (x[i] + x[i+1])/2
            y_mid1 = (y[i] + y[i+1])/2
        else:
            dist1 = round(distance(x[i],y[i],x[0],y[0]),2)
            x_mid1 = (x[i] + x[0])/2
            y_mid1 = (y[i] + y[0])/2
        dist.append(dist1)
        x_mid.append(x_mid1)
        y_mid.append(y_mid1) 
    
    
    source = ColumnDataSource(data=dict(x_mid = x_mid,y_mid = y_mid,dist = dist))
    
    p.line(x, y)      
    p.scatter(x, y)
    
    labels = LabelSet(x= 'x_mid', y= 'y_mid', text='dist', level='glyph',
                  x_offset=5, y_offset=5, source= source, render_mode='canvas', text_font_size="8pt")
    
    p.add_layout(labels)
    show(p)
    

    enter image description here